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 javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils; 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.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
@@ -30,128 +33,103 @@ import org.springframework.stereotype.Component;
@Scope("singleton") @Scope("singleton")
public class AuditApiResource { public class AuditApiResource {
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>( private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "apiOperation", "resource", "resourceId",
Arrays.asList("id", "apiOperation", "resource", "resourceId", "maker", "madeOnDate", "checker", "checkedOnDate", "commandAsJson"));
"maker", "madeOnDate", "checker", "checkedOnDate",
"commandAsJson"));
private final String resourceNameForPermissions = "AUDIT";
private final PlatformSecurityContext context; private final String resourceNameForPermissions = "AUDIT";
private final AuditReadPlatformService auditReadPlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializer;
private final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate;
@Autowired private final PlatformSecurityContext context;
public AuditApiResource( private final AuditReadPlatformService auditReadPlatformService;
final PlatformSecurityContext context, private final ApiRequestParameterHelper apiRequestParameterHelper;
final AuditReadPlatformService auditReadPlatformService, private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializer;
final ApiRequestParameterHelper apiRequestParameterHelper, private final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate;
final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializer,
final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate) {
this.context = context;
this.auditReadPlatformService = auditReadPlatformService;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.toApiJsonSerializer = toApiJsonSerializer;
this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate;
}
@GET @Autowired
@Consumes({ MediaType.APPLICATION_JSON }) public AuditApiResource(final PlatformSecurityContext context, final AuditReadPlatformService auditReadPlatformService,
@Produces({ MediaType.APPLICATION_JSON }) final ApiRequestParameterHelper apiRequestParameterHelper, final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializer,
public String retrieveAuditEntries(@Context final UriInfo uriInfo, final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate) {
@QueryParam("apiOperation") final String apiOperation, this.context = context;
@QueryParam("resource") final String resource, this.auditReadPlatformService = auditReadPlatformService;
@QueryParam("resourceId") final Long resourceId, this.apiRequestParameterHelper = apiRequestParameterHelper;
@QueryParam("makerId") final Long makerId, this.toApiJsonSerializer = toApiJsonSerializer;
@QueryParam("checkerId") final Long checkerId) { this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate;
}
context.authenticatedUser().validateHasReadPermission( @GET
resourceNameForPermissions); @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, context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
resourceId, makerId, checkerId);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper final String extraCriteria = getExtraCriteria(apiOperation, resource, resourceId, makerId, checkerId);
.process(uriInfo.getQueryParameters());
final Collection<AuditData> auditEntries = this.auditReadPlatformService final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
.retrieveAuditEntries(extraCriteria, settings.isIncludeJson());
return this.toApiJsonSerializer.serialize(settings, auditEntries, final Collection<AuditData> auditEntries = this.auditReadPlatformService.retrieveAuditEntries(extraCriteria,
RESPONSE_DATA_PARAMETERS); settings.isIncludeJson());
}
@GET return this.toApiJsonSerializer.serialize(settings, auditEntries, RESPONSE_DATA_PARAMETERS);
@Path("{auditId}") }
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAuditEntry(@PathParam("auditId") final Long auditId,
@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission( @GET
resourceNameForPermissions); @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 context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
.process(uriInfo.getQueryParameters());
final AuditData auditEntry = this.auditReadPlatformService final AuditData auditEntry = this.auditReadPlatformService.retrieveAuditEntry(auditId);
.retrieveAuditEntry(auditId);
return this.toApiJsonSerializer.serialize(settings, auditEntry, final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
RESPONSE_DATA_PARAMETERS); return this.toApiJsonSerializer.serialize(settings, auditEntry, RESPONSE_DATA_PARAMETERS);
} }
@GET @GET
@Path("/searchtemplate") @Path("/searchtemplate")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveAuditSearchTemplate(@Context final UriInfo uriInfo) { public String retrieveAuditSearchTemplate(@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission( context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
resourceNameForPermissions);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
.process(uriInfo.getQueryParameters());
final AuditSearchData auditSearchData = this.auditReadPlatformService final AuditSearchData auditSearchData = this.auditReadPlatformService.retrieveSearchTemplate();
.retrieveSearchTemplate();
final Set<String> RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE = new HashSet<String>( final Set<String> RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE = new HashSet<String>(Arrays.asList("appUsers", "apiOperations",
Arrays.asList("appUsers", "apiOperations", "resources")); "resources"));
return this.toApiJsonSerializerSearchTemplate.serialize(settings, auditSearchData, return this.toApiJsonSerializerSearchTemplate.serialize(settings, auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE);
RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE); }
}
private String getExtraCriteria(String apiOperation, String resource, private String getExtraCriteria(final String apiOperation, final String resource, final Long resourceId, final Long makerId, final Long checkerId) {
Long resourceId, Long makerId, Long checkerId) {
String extraCriteria = ""; String extraCriteria = "";
if (apiOperation != null) { if (apiOperation != null) {
extraCriteria += " and aud.api_operation = " extraCriteria += " and aud.api_operation = " + ApiParameterHelper.sqlEncodeString(apiOperation);
+ ApiParameterHelper.sqlEncodeString(apiOperation); }
} if (resource != null) {
if (resource != null) { extraCriteria += " and aud.api_resource = " + ApiParameterHelper.sqlEncodeString(resource);
extraCriteria += " and aud.api_resource = " }
+ ApiParameterHelper.sqlEncodeString(resource); if (resourceId != null) {
} extraCriteria += " and aud.resource_id = " + resourceId;
if (resourceId != null) { }
extraCriteria += " and aud.resource_id = " + resourceId; if (makerId != null) {
} extraCriteria += " and aud.maker_id = " + makerId;
if (makerId != null) { }
extraCriteria += " and aud.maker_id = " + makerId; if (checkerId != null) {
} extraCriteria += " and aud.checker_id = " + checkerId;
if (checkerId != null) { }
extraCriteria += " and aud.checker_id = " + checkerId;
}
if (StringUtils.isNotBlank(extraCriteria)) { if (StringUtils.isNotBlank(extraCriteria)) {
extraCriteria = extraCriteria.substring(4); extraCriteria = extraCriteria.substring(4);
} }
return extraCriteria;
}
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; import org.joda.time.LocalDate;
/** /**
* Immutable data object representing client data. * Immutable data object representing client data.
*/ */
final public class AuditData { public final class AuditData {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Long id; 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); 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 javax.persistence.TemporalType;
import org.apache.commons.lang.StringUtils; 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.mifosplatform.useradministration.domain.AppUser;
import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.data.jpa.domain.AbstractPersistable;
@@ -19,24 +20,35 @@ import org.springframework.data.jpa.domain.AbstractPersistable;
@Table(name = "m_portfolio_command_source") @Table(name = "m_portfolio_command_source")
public class CommandSource extends AbstractPersistable<Long> { 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; private String apiOperation;
@Column(name = "api_resource", length = 20) @Column(name = "api_resource", length = 100)
private String resource; private String resource;
@Column(name = "resource_id") @Column(name = "resource_id")
private Long resourceId; 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) @Column(name = "command_as_json", length = 1000)
private String commandAsJson; private String commandAsJson;
@SuppressWarnings("unused")
@ManyToOne @ManyToOne
@JoinColumn(name = "maker_id", nullable = false) @JoinColumn(name = "maker_id", nullable = false)
private AppUser maker; private AppUser maker;
@SuppressWarnings("unused")
@Column(name = "made_on_date", nullable = false) @Column(name = "made_on_date", nullable = false)
@Temporal(TemporalType.DATE) @Temporal(TemporalType.TIMESTAMP)
private Date madeOnDate; private Date madeOnDate;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@@ -46,37 +58,33 @@ public class CommandSource extends AbstractPersistable<Long> {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Column(name = "checked_on_date", nullable = false) @Column(name = "checked_on_date", nullable = false)
@Temporal(TemporalType.DATE) @Temporal(TemporalType.TIMESTAMP)
private Date checkedOnDate; private Date checkedOnDate;
public static CommandSource createdBy(final String apiOperation, final String resource, final Long resourceId, public static CommandSource fullEntryFrom(final CommandWrapper wrapper, final JsonCommand command, final AppUser maker) {
final String commandSerializedAsJson, final AppUser maker, final LocalDate madeOnDate) { return new CommandSource(wrapper.taskPermissionName(), wrapper.operation(), wrapper.resourceName(), command.resourceId(),
return new CommandSource(apiOperation, resource, resourceId, commandSerializedAsJson, maker, madeOnDate); wrapper.subResourceName(), command.subResourceId(), command.json(), maker, DateTime.now());
} }
protected CommandSource() { protected CommandSource() {
// //
} }
private CommandSource(final String apiOperation, final String resource, final Long resourceId, final String commandSerializedAsJson, final AppUser maker, private CommandSource(final String permissionCode, final String apiOperation, final String resource, final Long resourceId,
final LocalDate madeOnDate) { 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.apiOperation = StringUtils.defaultIfEmpty(apiOperation, null);
this.resource = StringUtils.defaultIfEmpty(resource, null); this.resource = StringUtils.defaultIfEmpty(resource, null);
this.resourceId = resourceId; this.resourceId = resourceId;
this.subResource = StringUtils.defaultIfEmpty(subResource, null);
this.subResourceId = subResourceId;
this.commandAsJson = commandSerializedAsJson; this.commandAsJson = commandSerializedAsJson;
this.maker = maker; this.maker = maker;
this.madeOnDate = madeOnDate.toDate(); this.madeOnDate = madeOnDateTime.toDate();
} }
public CommandSource copy() { public void markAsChecked(final AppUser checker, final DateTime checkedOnDate) {
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) {
this.checker = checker; this.checker = checker;
this.checkedOnDate = checkedOnDate.toDate(); this.checkedOnDate = checkedOnDate.toDate();
} }
@@ -85,6 +93,10 @@ public class CommandSource extends AbstractPersistable<Long> {
this.resourceId = resourceId; this.resourceId = resourceId;
} }
public void updateSubResourceId(final Long subResourceId) {
this.subResourceId = subResourceId;
}
public void updateJsonTo(final String json) { public void updateJsonTo(final String json) {
this.commandAsJson = json; this.commandAsJson = json;
} }
@@ -113,81 +125,23 @@ public class CommandSource extends AbstractPersistable<Long> {
return this.apiOperation; return this.apiOperation;
} }
public boolean isCreate() { public String getPermissionCode() {
return this.apiOperation.equalsIgnoreCase("CREATE"); return this.permissionCode;
} }
public boolean isUpdate() { public String getResource() {
// permissions resource has special update which involves no resource. return this.resource;
return (isPermissionResource() && isUpdateOperation()) || (isCurrencyResource() && isUpdateOperation())
|| (isUpdateOperation() && this.resourceId != null);
} }
private boolean isUpdateOperation() { public Long getResourceId() {
return this.apiOperation.equalsIgnoreCase("UPDATE"); return this.resourceId;
} }
public boolean isDelete() { public String getSubResource() {
return this.apiOperation.equalsIgnoreCase("DELETE") && this.resourceId != null; return this.subResource;
} }
public boolean isUpdateRolePermissions() { public Long getSubResourceId() {
return this.apiOperation.equalsIgnoreCase("UPDATEPERMISSIONS") && this.resourceId != null; return this.subResourceId;
}
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");
} }
} }
@@ -3,8 +3,6 @@ package org.mifosplatform.commands.domain;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface CommandSourceRepository extends public interface CommandSourceRepository extends JpaRepository<CommandSource, Long>, JpaSpecificationExecutor<CommandSource> {
JpaRepository<CommandSource, Long>, // no added behaviour
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 { 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); EntityIdentifier approveEntry(Long id);
@@ -1,62 +1,107 @@
package org.mifosplatform.commands.service; 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.CommandSource;
import org.mifosplatform.commands.domain.CommandSourceRepository; 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.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; 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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.google.gson.JsonElement;
@Service @Service
public class PortfolioCommandSourceWritePlatformServiceImpl implements PortfolioCommandSourceWritePlatformService { public class PortfolioCommandSourceWritePlatformServiceImpl implements PortfolioCommandSourceWritePlatformService {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final CommandSourceRepository commandSourceRepository; private final CommandSourceRepository commandSourceRepository;
private final CommandSourceHandlerDelegator commandSourceHandlerDelegator; private final FromJsonHelper fromApiJsonHelper;
private final CommandProcessingService processAndLogCommandService;
@Autowired @Autowired
public PortfolioCommandSourceWritePlatformServiceImpl(final PlatformSecurityContext context, public PortfolioCommandSourceWritePlatformServiceImpl(final PlatformSecurityContext context,
final CommandSourceRepository makerCheckerRepository, final CommandSourceHandlerDelegator commandSourceHandlerDelegator) { final CommandSourceRepository commandSourceRepository, final FromJsonHelper fromApiJsonHelper,
final CommandProcessingService processAndLogCommandService) {
this.context = context; this.context = context;
this.commandSourceRepository = makerCheckerRepository; this.commandSourceRepository = commandSourceRepository;
this.commandSourceHandlerDelegator = commandSourceHandlerDelegator; this.fromApiJsonHelper = fromApiJsonHelper;
this.processAndLogCommandService = processAndLogCommandService;
} }
// NOT TRANSACTIONAL BY DESIGN FOR NOW
@Override @Override
public EntityIdentifier logCommandSource(final String apiOperation, final String resource, final Long resourceId, public EntityIdentifier logCommandSource(final String taskPermissionName, final String apiOperation, final String resource,
final String commandSerializedAsJson) { final Long resourceId, final String subResource, final Long subRescourceId, final String json) {
final AppUser maker = context.authenticatedUser(); context.authenticatedUser().validateHasPermissionTo(taskPermissionName);
final LocalDate asToday = new LocalDate();
final CommandSource commandSourceInput = CommandSource.createdBy(apiOperation, resource, resourceId, commandSerializedAsJson, maker, asToday); final CommandWrapper wrapper = CommandWrapper.wrap(taskPermissionName, apiOperation, resource, resourceId, subResource, subRescourceId);
final CommandSource commandSourceResult = this.commandSourceHandlerDelegator.handleCommandWithSupportForRollback(commandSourceInput); 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) {
if (commandSourceResult.hasJson()) { final String jsonToUse = StringUtils.defaultIfEmpty(e.getJsonOfChangesOnly(), json);
commandSourceRepository.save(commandSourceResult);
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 @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 CommandWrapper wrapper = CommandWrapper.wrap(taskPermissionName, apiOperation, resource, resourceId);
final CommandSource commandSourceResult = this.commandSourceHandlerDelegator.handleCommandForCheckerApproval(commandSourceInput);
if (commandSourceResult.hasJson()) { EntityIdentifier result = null;
commandSourceRepository.save(commandSourceResult); 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 @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.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
@@ -76,10 +75,7 @@ public class CodesApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String createCode(final String apiRequestBodyAsJson) { public String createCode(final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "CREATE_CODE"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CODE", "CREATE", "codes", null,
context.authenticatedUser().validateHasPermissionTo("CREATE_CODE", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "codes", null,
apiRequestBodyAsJson); apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
@@ -103,10 +99,7 @@ public class CodesApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateCode(@PathParam("codeId") final Long codeId, final String apiRequestBodyAsJson) { public String updateCode(@PathParam("codeId") final Long codeId, final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "UPDATE_CODE"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CODE", "UPDATE", "codes", codeId,
context.authenticatedUser().validateHasPermissionTo("UPDATE_CODE", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "codes", codeId,
apiRequestBodyAsJson); apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
@@ -118,10 +111,8 @@ public class CodesApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String deleteCodeApplication(@PathParam("codeId") final Long codeId) { public String deleteCodeApplication(@PathParam("codeId") final Long codeId) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "DELETE_CODE"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE_CODE", "DELETE", "codes", codeId,
context.authenticatedUser().validateHasPermissionTo("DELETE_CODE", allowedPermissions); "{}");
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "codes", codeId, "{}");
return this.toApiJsonSerializer.serialize(result); 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.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.codes.command.CodeCommand; 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.AbstractFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer; import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -30,16 +31,16 @@ public final class CodeCommandFromApiJsonDeserializer extends AbstractFromApiJso
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
@Autowired @Autowired
public CodeCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper, final CommandSerializer commandSerializerService) { public CodeCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
super(commandSerializerService);
this.fromApiJsonHelper = fromApiJsonHelper; this.fromApiJsonHelper = fromApiJsonHelper;
} }
@Override @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(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final JsonElement element = fromApiJsonHelper.parse(json); final JsonElement element = fromApiJsonHelper.parse(json);
@@ -5,9 +5,9 @@ import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
public interface CodeWritePlatformService { public interface CodeWritePlatformService {
Long createCode(JsonCommand command); EntityIdentifier createCode(JsonCommand command);
EntityIdentifier updateCode(Long codeId, 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.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -28,22 +26,19 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final CodeRepository codeRepository; private final CodeRepository codeRepository;
private final ConfigurationDomainService configurationDomainService;
private final CodeCommandFromApiJsonDeserializer fromApiJsonDeserializer; private final CodeCommandFromApiJsonDeserializer fromApiJsonDeserializer;
@Autowired @Autowired
public CodeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final CodeRepository codeRepository, public CodeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final CodeRepository codeRepository,
final ConfigurationDomainService configurationDomainService,
final CodeCommandFromApiJsonDeserializer fromApiJsonDeserializer) { final CodeCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
this.context = context; this.context = context;
this.codeRepository = codeRepository; this.codeRepository = codeRepository;
this.configurationDomainService = configurationDomainService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.fromApiJsonDeserializer = fromApiJsonDeserializer;
} }
@Transactional @Transactional
@Override @Override
public Long createCode(final JsonCommand command) { public EntityIdentifier createCode(final JsonCommand command) {
try { try {
context.authenticatedUser(); context.authenticatedUser();
@@ -54,11 +49,9 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
final Code code = Code.fromJson(command); final Code code = Code.fromJson(command);
this.codeRepository.save(code); this.codeRepository.save(code);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("CREATE_CODE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } return EntityIdentifier.resourceResult(code.getId(), null);
return code.getId();
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
return Long.valueOf(-1); return EntityIdentifier.empty();
} }
} }
@@ -78,8 +71,6 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
this.codeRepository.save(code); this.codeRepository.save(code);
} }
if (this.configurationDomainService.isMakerCheckerEnabledForTask("UPDATE_CODE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return EntityIdentifier.withChanges(codeId, changes); return EntityIdentifier.withChanges(codeId, changes);
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
handleCodeDataIntegrityIssues(command, dve); handleCodeDataIntegrityIssues(command, dve);
@@ -89,19 +80,15 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
@Transactional @Transactional
@Override @Override
public EntityIdentifier deleteCode(final Long codeId, final JsonCommand command) { public EntityIdentifier deleteCode(final Long codeId) {
context.authenticatedUser(); context.authenticatedUser();
final Code code = retrieveCodeBy(codeId); final Code code = retrieveCodeBy(codeId);
if (code.isSystemDefined()) { if (code.isSystemDefined()) { throw new SystemDefinedCodeCannotBeChangedException(); }
throw new SystemDefinedCodeCannotBeChangedException();
}
this.codeRepository.delete(code); this.codeRepository.delete(code);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("DELETE_CODE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return new EntityIdentifier(code.getId()); return new EntityIdentifier(code.getId());
} }
@@ -119,8 +106,8 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
Throwable realCause = dve.getMostSpecificCause(); Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("code_name_org")) { if (realCause.getMessage().contains("code_name_org")) {
final String name = command.stringValueOfParameterNamed("name"); final String name = command.stringValueOfParameterNamed("name");
throw new PlatformDataIntegrityException("error.msg.code.duplicate.name", throw new PlatformDataIntegrityException("error.msg.code.duplicate.name", "A code with name '" + name + "' already exists");
"A code with name '" + name + "' already exists"); } }
logger.error(dve.getMessage(), dve); logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.cund.unknown.data.integrity.issue", throw new PlatformDataIntegrityException("error.msg.cund.unknown.data.integrity.issue",
@@ -1,9 +1,11 @@
package org.mifosplatform.infrastructure.core.api; package org.mifosplatform.infrastructure.core.api;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
@@ -23,36 +25,49 @@ import com.google.gson.reflect.TypeToken;
public final class JsonCommand { public final class JsonCommand {
private final String jsonCommand; private final String jsonCommand;
private final transient boolean approvedByChecker;
private final JsonElement parsedCommand; private final JsonElement parsedCommand;
private final FromJsonHelper fromApiJsonHelper; 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) { public static JsonCommand from(final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper,
return new JsonCommand(jsonCommand, parsedCommand, fromApiJsonHelper, false); final Long resourceId, final Long subResourceId) {
return new JsonCommand(null, jsonCommand, parsedCommand, fromApiJsonHelper, resourceId, subResourceId);
} }
public static JsonCommand withMakerCheckerApproval(final String jsonCommand, final JsonElement parsedCommand, public static JsonCommand fromExistingCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper,
final FromJsonHelper fromApiJsonHelper) { final Long resourceId, final Long subResourceId) {
return new JsonCommand(jsonCommand, parsedCommand, fromApiJsonHelper, true); return new JsonCommand(commandId, jsonCommand, parsedCommand, fromApiJsonHelper, resourceId, subResourceId);
} }
public JsonCommand(final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper, public JsonCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper,
final boolean approvedByChecker) { final Long resourceId, final Long subResourceId) {
this.commandId = commandId;
this.jsonCommand = jsonCommand; this.jsonCommand = jsonCommand;
this.parsedCommand = parsedCommand; this.parsedCommand = parsedCommand;
this.fromApiJsonHelper = fromApiJsonHelper; this.fromApiJsonHelper = fromApiJsonHelper;
this.approvedByChecker = approvedByChecker; this.resourceId = resourceId;
this.subResourceId = subResourceId;
} }
public String json() { public String json() {
return this.jsonCommand; return this.jsonCommand;
} }
public boolean isApprovedByChecker() { public Long commandId() {
return this.approvedByChecker; return this.commandId;
} }
private boolean differenceExists(LocalDate baseValue, LocalDate workingCopyValue) { public Long resourceId() {
return this.resourceId;
}
public Long subResourceId() {
return this.subResourceId;
}
private boolean differenceExists(final LocalDate baseValue, final LocalDate workingCopyValue) {
boolean differenceExists = false; boolean differenceExists = false;
if (baseValue != null) { if (baseValue != null) {
@@ -82,7 +97,31 @@ public final class JsonCommand {
return !Arrays.equals(baseValue, workingCopyValue); 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; boolean differenceExists = false;
if (baseValue != null) { if (baseValue != null) {
@@ -160,6 +199,56 @@ public final class JsonCommand {
return StringUtils.defaultIfEmpty(value, ""); 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) { public boolean isChangeInArrayParameterNamed(final String parameterName, final String[] existingValue) {
boolean isChanged = false; boolean isChanged = false;
if (parameterExists(parameterName)) { if (parameterExists(parameterName)) {
@@ -173,7 +262,8 @@ public final class JsonCommand {
return this.fromApiJsonHelper.extractArrayNamed(parameterName, parsedCommand); 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; boolean isChanged = false;
if (parameterExists(parameterName)) { if (parameterExists(parameterName)) {
final String workingValue = passwordValueOfParameterNamed(parameterName, platformPasswordEncoder, saltValue); final String workingValue = passwordValueOfParameterNamed(parameterName, platformPasswordEncoder, saltValue);
@@ -182,7 +272,8 @@ public final class JsonCommand {
return isChanged; 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 String passwordPlainText = stringValueOfParameterNamed(parameterName);
final PlatformUser dummyPlatformUser = new BasicPasswordEncodablePlatformUser(saltValue, "", passwordPlainText); final PlatformUser dummyPlatformUser = new BasicPasswordEncodablePlatformUser(saltValue, "", passwordPlainText);
@@ -134,7 +134,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
@Override @Override
public ClientData convertInternalJsonFormatToClientDataChange(final Long resourceIdentifier, final String json) { 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(), return ClientData.dataChangeInstance(resourceIdentifier, command.getOfficeId(), command.getExternalId(), command.getFirstname(),
command.getLastname(), command.getClientOrBusinessName(), command.getJoiningDate()); command.getLastname(), command.getClientOrBusinessName(), command.getJoiningDate());
@@ -5,55 +5,71 @@ import java.util.Map;
/** /**
* Represents the successful result of an REST API call. * Represents the successful result of an REST API call.
*
* FIXME - KW - Rename to CommandProcessingResult - make immutable
*/ */
public class EntityIdentifier { public class EntityIdentifier {
private Long entityId; private Long commandId;
private Long resourceId;
// TODO - Rename variable to commandId or taskId or something that shows private Long subResourceId;
// this is the id of a command in a table/queue for processing.
@SuppressWarnings("unused")
private Long makerCheckerId;
private Map<String, Object> changes; private Map<String, Object> changes;
public static EntityIdentifier makerChecker(final Long makerCheckerId) { public static EntityIdentifier commandOnlyResult(final Long commandId) {
return new EntityIdentifier(null, makerCheckerId, null); return new EntityIdentifier(null, null, commandId, null);
} }
public static EntityIdentifier makerChecker(final Long resourceId, final Long makerCheckerId) { public static EntityIdentifier resourceResult(final Long resourceId, final Long commandId) {
return new EntityIdentifier(resourceId, makerCheckerId, null); 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) { public static EntityIdentifier withChanges(final Long resourceId, final Map<String, Object> changes) {
return new EntityIdentifier(resourceId, null, changes); return new EntityIdentifier(resourceId, null, null, changes);
} }
public static EntityIdentifier empty() { public static EntityIdentifier empty() {
return new EntityIdentifier(Long.valueOf(-1), null, null); return new EntityIdentifier(Long.valueOf(-1), Long.valueOf(-1), Long.valueOf(-1), null);
} }
public EntityIdentifier() { protected EntityIdentifier() {
// //
} }
public EntityIdentifier(final Long entityId) { public EntityIdentifier(final Long entityId) {
this.entityId = entityId; this.resourceId = entityId;
this.changes = new HashMap<String, Object>(); this.changes = new HashMap<String, Object>();
} }
private EntityIdentifier(final Long entityId, final Long makerCheckerId, final Map<String, Object> changesOnly) { private EntityIdentifier(final Long resourceId, final Long subResourceId, final Long commandId, final Map<String, Object> changesOnly) {
this.entityId = entityId; this.resourceId = resourceId;
this.makerCheckerId = makerCheckerId; this.subResourceId = subResourceId;
this.commandId = commandId;
this.changes = changesOnly; this.changes = changesOnly;
} }
public Long getEntityId() { public Long commandId() {
return this.entityId; return this.commandId;
} }
public void setEntityId(final Long entityId) { public Long resourceId() {
this.entityId = entityId; return this.resourceId;
}
public Long subResourceId() {
return this.subResourceId;
} }
public Map<String, Object> getChanges() { public Map<String, Object> getChanges() {
@@ -63,4 +79,9 @@ public class EntityIdentifier {
} }
return checkIfEmpty; 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> { public abstract class AbstractFromApiJsonDeserializer<T> implements FromApiJsonDeserializer<T> {
private final CommandSerializer commandSerializerService;
public AbstractFromApiJsonDeserializer(final CommandSerializer commandSerializerService) {
this.commandSerializerService = commandSerializerService;
}
@Override @Override
public T commandFromApiJson(final String json) { public abstract 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);
}
} }
@@ -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,18 +17,26 @@ public final class DefaultToApiJsonSerializer<T> implements ToApiJsonSerializer<
private final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOff; private final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOff;
private final ExcludeNothingWithPrettyPrintingOnJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOn; private final ExcludeNothingWithPrettyPrintingOnJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOn;
private final CommandProcessingResultJsonSerializer commandProcessingResultSerializer;
private final GoogleGsonSerializerHelper helper; private final GoogleGsonSerializerHelper helper;
@Autowired @Autowired
public DefaultToApiJsonSerializer( public DefaultToApiJsonSerializer(
final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOff, final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOff,
final ExcludeNothingWithPrettyPrintingOnJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOn, final ExcludeNothingWithPrettyPrintingOnJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOn,
final CommandProcessingResultJsonSerializer commandProcessingResultSerializer,
final GoogleGsonSerializerHelper helper) { final GoogleGsonSerializerHelper helper) {
this.excludeNothingWithPrettyPrintingOff = excludeNothingWithPrettyPrintingOff; this.excludeNothingWithPrettyPrintingOff = excludeNothingWithPrettyPrintingOff;
this.excludeNothingWithPrettyPrintingOn = excludeNothingWithPrettyPrintingOn; this.excludeNothingWithPrettyPrintingOn = excludeNothingWithPrettyPrintingOn;
this.commandProcessingResultSerializer = commandProcessingResultSerializer;
this.helper = helper; this.helper = helper;
} }
@Override
public String serializeResult(final Object object) {
return this.commandProcessingResultSerializer.serialize(object);
}
@Override @Override
public String serialize(final Object object) { public String serialize(final Object object) {
return this.excludeNothingWithPrettyPrintingOff.serialize(object); return this.excludeNothingWithPrettyPrintingOff.serialize(object);
@@ -6,10 +6,4 @@ package org.mifosplatform.infrastructure.core.serialization;
public interface FromApiJsonDeserializer<T> { public interface FromApiJsonDeserializer<T> {
T commandFromApiJson(final String json); 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);
} }
@@ -87,6 +87,10 @@ public class FromJsonHelper {
return helperDelegator.extractArrayNamed(parameterName, element, 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) { public Boolean extractBooleanNamed(final String parameterName, final JsonElement element, final Set<String> parametersPassedInRequest) {
return helperDelegator.extractBooleanNamed(parameterName, element, parametersPassedInRequest); return helperDelegator.extractBooleanNamed(parameterName, element, parametersPassedInRequest);
} }
@@ -105,6 +109,10 @@ public class FromJsonHelper {
return helperDelegator.extractLocalDateAsArrayNamed(parameterName, element, parametersPassedInRequest); 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, public BigDecimal extractBigDecimalWithLocaleNamed(final String parameterName, final JsonElement element,
final Set<String> parametersPassedInRequest) { final Set<String> parametersPassedInRequest) {
return helperDelegator.extractBigDecimalWithLocaleNamed(parameterName, element, parametersPassedInRequest); return helperDelegator.extractBigDecimalWithLocaleNamed(parameterName, element, parametersPassedInRequest);
@@ -115,6 +123,10 @@ public class FromJsonHelper {
return helperDelegator.extractBigDecimalNamed(parameterName, element.getAsJsonObject(), Locale.US, parametersPassedInRequest); 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, public Integer extractIntegerWithLocaleNamed(final String parameterName, final JsonElement element,
final Set<String> parametersPassedInRequest) { final Set<String> parametersPassedInRequest) {
return helperDelegator.extractIntegerWithLocaleNamed(parameterName, element.getAsJsonObject(), parametersPassedInRequest); return helperDelegator.extractIntegerWithLocaleNamed(parameterName, element.getAsJsonObject(), parametersPassedInRequest);
@@ -7,6 +7,8 @@ public interface ToApiJsonSerializer<T> {
String serialize(final Object object); String serialize(final Object object);
String serializeResult(final Object object);
String serialize(final ApiRequestJsonSerializationSettings settings, Collection<T> collection, Set<String> supportedResponseParameters); String serialize(final ApiRequestJsonSerializationSettings settings, Collection<T> collection, Set<String> supportedResponseParameters);
String serialize(final ApiRequestJsonSerializationSettings settings, T single, Set<String> supportedResponseParameters); String serialize(final ApiRequestJsonSerializationSettings settings, T single, Set<String> supportedResponseParameters);
@@ -77,8 +77,7 @@ public class DataTableApiResource {
this.readWriteNonCoreDataService.registerDatatable(datatable, apptable); this.readWriteNonCoreDataService.registerDatatable(datatable, apptable);
EntityIdentifier entityIdentifier = new EntityIdentifier(); return Response.ok().entity(EntityIdentifier.empty()).build();
return Response.ok().entity(entityIdentifier).build();
} }
@POST @POST
@@ -89,8 +88,7 @@ public class DataTableApiResource {
this.readWriteNonCoreDataService.deregisterDatatable(datatable); this.readWriteNonCoreDataService.deregisterDatatable(datatable);
EntityIdentifier entityIdentifier = new EntityIdentifier(); return Response.ok().entity(EntityIdentifier.empty()).build();
return Response.ok().entity(entityIdentifier).build();
} }
@GET @GET
@@ -2,7 +2,6 @@ package org.mifosplatform.organisation.monetary.api;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import javax.ws.rs.Consumes; 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.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.data.ConfigurationData; import org.mifosplatform.organisation.monetary.data.ConfigurationData;
import org.mifosplatform.organisation.monetary.serialization.CurrencyCommandFromApiJsonDeserializer;
import org.mifosplatform.organisation.monetary.service.OrganisationCurrencyReadPlatformService; import org.mifosplatform.organisation.monetary.service.OrganisationCurrencyReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
@@ -38,20 +36,17 @@ public class CurrenciesApiResource {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final OrganisationCurrencyReadPlatformService readPlatformService; private final OrganisationCurrencyReadPlatformService readPlatformService;
private final CurrencyCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<ConfigurationData> toApiJsonSerializer; private final DefaultToApiJsonSerializer<ConfigurationData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper; private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired @Autowired
public CurrenciesApiResource(final PlatformSecurityContext context, final OrganisationCurrencyReadPlatformService readPlatformService, public CurrenciesApiResource(final PlatformSecurityContext context, final OrganisationCurrencyReadPlatformService readPlatformService,
final CurrencyCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<ConfigurationData> toApiJsonSerializer, final DefaultToApiJsonSerializer<ConfigurationData> toApiJsonSerializer,
final ApiRequestParameterHelper apiRequestParameterHelper, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context; this.context = context;
this.readPlatformService = readPlatformService; this.readPlatformService = readPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer; this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper; this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -75,13 +70,8 @@ public class CurrenciesApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateCurrencies(final String apiRequestBodyAsJson) { public String updateCurrencies(final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "UPDATE_CURRENCY"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CURRENCY", "UPDATE", "currencies",
context.authenticatedUser().validateHasPermissionTo("UPDATE_CURRENCY", allowedPermissions); null, apiRequestBodyAsJson);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "currencies", null,
commandSerializedAsJson);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -5,16 +5,18 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; 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. * Immutable command for updating allowed currencies.
*/ */
public class CurrencyCommand { public class CurrencyCommand {
private String[] currencies; private String[] currencies;
private final transient boolean makerCheckerApproval;
public CurrencyCommand(final boolean makerCheckerApproval, final String[] currencies) { public CurrencyCommand(final String[] currencies) {
this.makerCheckerApproval = makerCheckerApproval;
final List<String> listOfCurrencyCodes = new ArrayList<String>(Arrays.asList(currencies)); final List<String> listOfCurrencyCodes = new ArrayList<String>(Arrays.asList(currencies));
Collections.sort(listOfCurrencyCodes); Collections.sort(listOfCurrencyCodes);
this.currencies = listOfCurrencyCodes.toArray(new String[listOfCurrencyCodes.size()]); this.currencies = listOfCurrencyCodes.toArray(new String[listOfCurrencyCodes.size()]);
@@ -24,7 +26,13 @@ public class CurrencyCommand {
return currencies; return currencies;
} }
public boolean isApprovedByChecker() { public void validateForUpdate() {
return this.makerCheckerApproval; 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.Map;
import java.util.Set; 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.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.monetary.command.CurrencyCommand; import org.mifosplatform.organisation.monetary.command.CurrencyCommand;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
/** /**
@@ -20,7 +23,7 @@ import com.google.gson.reflect.TypeToken;
* 's. * 's.
*/ */
@Component @Component
public final class CurrencyCommandFromApiJsonDeserializer implements FromApiJsonDeserializer<CurrencyCommand> { public final class CurrencyCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<CurrencyCommand> {
/** /**
* The parameters supported for this command. * 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 Set<String> supportedParameters = new HashSet<String>(Arrays.asList("currencies"));
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
private final CurrencyCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final CommandSerializer commandSerializerService;
@Autowired @Autowired
public CurrencyCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper, public CurrencyCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
final CurrencyCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final CommandSerializer commandSerializerService) {
this.fromApiJsonHelper = fromApiJsonHelper; this.fromApiJsonHelper = fromApiJsonHelper;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.commandSerializerService = commandSerializerService;
} }
@Override @Override
public CurrencyCommand commandFromApiJson(final String json) { public CurrencyCommand commandFromApiJson(final String json) {
return commandFromApiJson(null, json);
}
@Override if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
public CurrencyCommand commandFromApiJson(final Long resourceId, final String json) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
return this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId, json); final JsonElement element = fromApiJsonHelper.parse(json);
} final String[] currencies = fromApiJsonHelper.extractArrayNamed("currencies", element);
return new CurrencyCommand(currencies);
@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);
} }
} }
@@ -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; package org.mifosplatform.organisation.monetary.service;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.useradministration.domain.Permission; import org.mifosplatform.useradministration.domain.Permission;
import org.mifosplatform.useradministration.domain.PermissionRepository; import org.mifosplatform.useradministration.domain.PermissionRepository;
import org.mifosplatform.useradministration.exception.PermissionNotFoundException; import org.mifosplatform.useradministration.exception.PermissionNotFoundException;
@@ -23,10 +24,10 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
@Override @Override
public boolean isMakerCheckerEnabledForTask(final String taskPermissionCode) { public boolean isMakerCheckerEnabledForTask(final String taskPermissionCode) {
if (StringUtils.isBlank(taskPermissionCode)) { throw new PermissionNotFoundException(taskPermissionCode); }
final Permission thisTask = this.permissionRepository.findOneByCode(taskPermissionCode); final Permission thisTask = this.permissionRepository.findOneByCode(taskPermissionCode);
if (thisTask == null) { if (thisTask == null) { throw new PermissionNotFoundException(taskPermissionCode); }
throw new PermissionNotFoundException(taskPermissionCode);
}
return thisTask.hasMakerCheckerEnabled() && this.makerCheckerGloablConfigurationEnabled; return thisTask.hasMakerCheckerEnabled() && this.makerCheckerGloablConfigurationEnabled;
} }
@@ -1,9 +1,10 @@
package org.mifosplatform.organisation.monetary.service; 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 { 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.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.command.CurrencyCommand; import org.mifosplatform.organisation.monetary.command.CurrencyCommand;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency; import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepository; 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.OrganisationCurrency;
import org.mifosplatform.organisation.office.domain.OrganisationCurrencyRepository; import org.mifosplatform.organisation.office.domain.OrganisationCurrencyRepository;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -25,54 +27,48 @@ public class CurrencyWritePlatformServiceJpaRepositoryImpl implements CurrencyWr
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ApplicationCurrencyRepository applicationCurrencyRepository; private final ApplicationCurrencyRepository applicationCurrencyRepository;
private final OrganisationCurrencyRepository organisationCurrencyRepository; private final OrganisationCurrencyRepository organisationCurrencyRepository;
private final ConfigurationDomainService configurationDomainService; private final CurrencyCommandFromApiJsonDeserializer fromApiJsonDeserializer;
@Autowired @Autowired
public CurrencyWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, public CurrencyWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final CurrencyCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final ApplicationCurrencyRepository applicationCurrencyRepository, final ApplicationCurrencyRepository applicationCurrencyRepository,
final OrganisationCurrencyRepository organisationCurrencyRepository, final ConfigurationDomainService configurationDomainService) { final OrganisationCurrencyRepository organisationCurrencyRepository) {
this.context = context; this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.applicationCurrencyRepository = applicationCurrencyRepository; this.applicationCurrencyRepository = applicationCurrencyRepository;
this.organisationCurrencyRepository = organisationCurrencyRepository; this.organisationCurrencyRepository = organisationCurrencyRepository;
this.configurationDomainService = configurationDomainService;
} }
@Transactional @Transactional
@Override @Override
public void updateAllowedCurrencies(final CurrencyCommand command) { public EntityIdentifier updateAllowedCurrencies(final JsonCommand command) {
context.authenticatedUser(); context.authenticatedUser();
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); final CurrencyCommand currencyCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("configuration"); 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", final ApplicationCurrency currency = this.applicationCurrencyRepository.findOneByCode(currencyCode);
"Validation errors exist.", dataValidationErrors); } 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()) { allowedCurrencyCodes.add(currencyCode);
allowedCurrencies.add(allowedCurrency);
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);
}
} }
changes.put("currencies", allowedCurrencyCodes.toArray(new String[allowedCurrencyCodes.size()]));
this.organisationCurrencyRepository.deleteAll(); this.organisationCurrencyRepository.deleteAll();
this.organisationCurrencyRepository.save(allowedCurrencies); this.organisationCurrencyRepository.save(allowedCurrencies);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("UPDATE_CURRENCY") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } return EntityIdentifier.withChanges(null, changes);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
} }
} }
@@ -3,7 +3,6 @@ package org.mifosplatform.organisation.office.api;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import javax.ws.rs.Consumes; 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.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.data.OfficeTransactionData; import org.mifosplatform.organisation.office.data.OfficeTransactionData;
import org.mifosplatform.organisation.office.serialization.BranchMoneyTransferCommandFromApiJsonDeserializer;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService; import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
@@ -38,24 +36,20 @@ public class OfficeTransactionsApiResource {
"allowedOffices", "currencyOptions")); "allowedOffices", "currencyOptions"));
private final String resourceNameForReadPermissions = "OFFICE"; private final String resourceNameForReadPermissions = "OFFICE";
private final String resourceNameForPermissions = "OFFICETRANSACTION";
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final OfficeReadPlatformService readPlatformService; private final OfficeReadPlatformService readPlatformService;
private final BranchMoneyTransferCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<OfficeTransactionData> toApiJsonSerializer; private final DefaultToApiJsonSerializer<OfficeTransactionData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper; private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired @Autowired
public OfficeTransactionsApiResource(final PlatformSecurityContext context, final OfficeReadPlatformService readPlatformService, public OfficeTransactionsApiResource(final PlatformSecurityContext context, final OfficeReadPlatformService readPlatformService,
final BranchMoneyTransferCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<OfficeTransactionData> toApiJsonSerializer, final DefaultToApiJsonSerializer<OfficeTransactionData> toApiJsonSerializer,
final ApiRequestParameterHelper apiRequestParameterHelper, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context; this.context = context;
this.readPlatformService = readPlatformService; this.readPlatformService = readPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer; this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper; this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -93,19 +87,8 @@ public class OfficeTransactionsApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String transferMoneyFrom(final String apiRequestBodyAsJson) { public String transferMoneyFrom(final String apiRequestBodyAsJson) {
// TODO - complete permissions for office transactions when more final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_OFFICETRANSACTION", "CREATE",
// functionality add or it is replaced by simple accounting equivalent "officetransactions", null, apiRequestBodyAsJson);
// (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);
return this.toApiJsonSerializer.serialize(result); 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.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.data.OfficeData; import org.mifosplatform.organisation.office.data.OfficeData;
import org.mifosplatform.organisation.office.data.OfficeLookup; import org.mifosplatform.organisation.office.data.OfficeLookup;
import org.mifosplatform.organisation.office.serialization.OfficeCommandFromApiJsonDeserializer;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService; import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
@@ -48,19 +47,16 @@ public class OfficesApiResource {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final OfficeReadPlatformService readPlatformService; private final OfficeReadPlatformService readPlatformService;
private final OfficeCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<OfficeData> toApiJsonSerializer; private final DefaultToApiJsonSerializer<OfficeData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper; private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired @Autowired
public OfficesApiResource(final PlatformSecurityContext context, final OfficeReadPlatformService readPlatformService, public OfficesApiResource(final PlatformSecurityContext context, final OfficeReadPlatformService readPlatformService,
final OfficeCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<OfficeData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, final DefaultToApiJsonSerializer<OfficeData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context; this.context = context;
this.readPlatformService = readPlatformService; this.readPlatformService = readPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer; this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper; this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -101,13 +97,8 @@ public class OfficesApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String createOffice(final String apiRequestBodyAsJson) { public String createOffice(final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "CREATE_OFFICE"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_OFFICE", "CREATE", "offices",
context.authenticatedUser().validateHasPermissionTo("CREATE_OFFICE", allowedPermissions); null, apiRequestBodyAsJson);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "offices", null,
commandSerializedAsJson);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -137,13 +128,8 @@ public class OfficesApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateOffice(@PathParam("officeId") final Long officeId, final String apiRequestBodyAsJson) { 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"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_OFFICE", "UPDATE", "offices",
context.authenticatedUser().validateHasPermissionTo("UPDATE_OFFICE", allowedPermissions); officeId, apiRequestBodyAsJson);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "offices", officeId,
commandSerializedAsJson);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -3,7 +3,6 @@ package org.mifosplatform.organisation.office.command;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.ApiParameterError;
@@ -22,14 +21,8 @@ public class BranchMoneyTransferCommand {
private final BigDecimal transactionAmount; private final BigDecimal transactionAmount;
private final String description; private final String description;
private final transient Set<String> parametersPassedInRequest; public BranchMoneyTransferCommand(final Long fromOfficeId, final Long toOfficeId, final LocalDate transactionDate,
private final transient boolean makerCheckerApproval; final String currencyCode, final BigDecimal transactionAmount, final String description) {
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;
this.fromOfficeId = fromOfficeId; this.fromOfficeId = fromOfficeId;
this.toOfficeId = toOfficeId; this.toOfficeId = toOfficeId;
this.transactionDate = transactionDate; this.transactionDate = transactionDate;
@@ -62,14 +55,6 @@ public class BranchMoneyTransferCommand {
return description; return description;
} }
public boolean isFromOfficeIdChanged() {
return this.parametersPassedInRequest.contains("fromOfficeId");
}
public boolean isApprovedByChecker() {
return this.makerCheckerApproval;
}
public void validateBranchTransfer() { public void validateBranchTransfer() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
@@ -2,7 +2,6 @@ package org.mifosplatform.organisation.office.command;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.ApiParameterError;
@@ -14,31 +13,18 @@ import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidation
*/ */
public class OfficeCommand { public class OfficeCommand {
private final String name; private final String name;
private final String externalId; private final String externalId;
private final LocalDate openingDate; private final LocalDate openingDate;
private final Long parentId; private final Long parentId;
private final transient Set<String> modifiedParameters; public OfficeCommand(final String officeName, final String externalId, final Long parentId, final LocalDate openingDate) {
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;
this.name = officeName; this.name = officeName;
this.externalId = externalId; this.externalId = externalId;
this.parentId = parentId; this.parentId = parentId;
this.openingDate = openingDate; this.openingDate = openingDate;
} }
public Long getId() {
return id;
}
public String getName() { public String getName() {
return name; return name;
} }
@@ -55,26 +41,6 @@ public class OfficeCommand {
return parentId; 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() { public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
@@ -94,7 +60,6 @@ public class OfficeCommand {
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("office"); 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("name").value(this.name).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("openingDate").value(this.openingDate).ignoreIfNull().notBlank(); baseDataValidator.reset().parameter("openingDate").value(this.openingDate).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("externalId").value(this.externalId).ignoreIfNull().notExceedingLengthOf(100); baseDataValidator.reset().parameter("externalId").value(this.externalId).ignoreIfNull().notExceedingLengthOf(100);
@@ -1,8 +1,10 @@
package org.mifosplatform.organisation.office.domain; package org.mifosplatform.organisation.office.domain;
import java.util.Date; import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
@@ -17,17 +19,15 @@ import javax.persistence.UniqueConstraint;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; 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.CannotUpdateOfficeWithParentOfficeSameAsSelf;
import org.mifosplatform.organisation.office.exception.RootOfficeParentCannotBeUpdated; import org.mifosplatform.organisation.office.exception.RootOfficeParentCannotBeUpdated;
import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.domain.AppUser;
@Entity @Entity
@Table(name = "m_office", uniqueConstraints={ @Table(name = "m_office", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "name_org"),
@UniqueConstraint(columnNames = {"name"}, name="name_org"), @UniqueConstraint(columnNames = { "external_id" }, name = "externalid_org") })
@UniqueConstraint(columnNames = {"external_id"}, name="externalid_org")
})
public class Office extends AbstractAuditableCustom<AppUser, Long> { public class Office extends AbstractAuditableCustom<AppUser, Long> {
@OneToMany(fetch = FetchType.EAGER) @OneToMany(fetch = FetchType.EAGER)
@@ -36,30 +36,32 @@ public class Office extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id") @JoinColumn(name = "parent_id")
private Office parent; private Office parent;
@Column(name = "name", nullable = false, length=100) @Column(name = "name", nullable = false, length = 100)
private String name; private String name;
@Column(name = "hierarchy", nullable = false, length=50) @Column(name = "hierarchy", nullable = false, length = 50)
private String hierarchy; private String hierarchy;
@SuppressWarnings("unused") @Column(name = "opening_date", nullable = false)
@Column(name = "opening_date", nullable = false)
@Temporal(TemporalType.DATE) @Temporal(TemporalType.DATE)
private Date openingDate; private Date openingDate;
@SuppressWarnings("unused") @Column(name = "external_id", length = 100)
@Column(name = "external_id", length=100) private String externalId;
private String externalId;
public static Office headOffice(final String name, final LocalDate openingDate, final String externalId) { public static Office headOffice(final String name, final LocalDate openingDate, final String externalId) {
return new Office(null, name, openingDate, externalId); return new Office(null, name, openingDate, externalId);
} }
public static Office createNew(final Office parent, final String name, final LocalDate openingDate, final String externalId) { public static Office fromJson(final Office parentOffice, final JsonCommand command) {
return new Office(parent, name, openingDate, externalId);
} 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() { protected Office() {
this.openingDate = null; this.openingDate = null;
@@ -76,110 +78,136 @@ public class Office extends AbstractAuditableCustom<AppUser, Long> {
} }
if (StringUtils.isNotBlank(name)) { if (StringUtils.isNotBlank(name)) {
this.name = name.trim(); this.name = name.trim();
} else { } else {
this.name = null; this.name = null;
}
if (StringUtils.isNotBlank(externalId)) {
this.externalId = externalId.trim();
} else {
this.externalId = 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); this.children.add(office);
} }
public void update(final OfficeCommand command) { public Map<String, Object> update(final JsonCommand command) {
if (command.isNameChanged()) { final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(7);
this.name = StringUtils.defaultIfEmpty(command.getName(), null);
}
if (command.isExternalIdChanged()) { final String dateFormatAsInput = command.dateFormat();
this.externalId = StringUtils.defaultIfEmpty(command.getExternalId(), null); final String localeAsInput = command.locale();
}
if (command.isOpeningDateChanged()) { final String parentIdParamName = "parentId";
if (command.getOpeningDate() != null) { if (command.isChangeInLongParameterNamed(parentIdParamName, this.parent.getId())) {
this.openingDate = command.getOpeningDate().toDate(); final Long newValue = command.longValueOfParameterNamed(parentIdParamName);
} else { actualChanges.put(parentIdParamName, newValue);
this.openingDate = null; }
}
}
}
public void update(final Office newParent) { 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);
if (this.parent == null) { final LocalDate newValue = command.localDateValueOfParameterNamed(openingDateParamName);
throw new RootOfficeParentCannotBeUpdated(); this.openingDate = newValue.toDate();
} }
if (this.identifiedBy(newParent.getId())) { final String nameParamName = "name";
throw new CannotUpdateOfficeWithParentOfficeSameAsSelf(this.getId(), newParent.getId()); if (command.isChangeInStringParameterNamed(nameParamName, this.name)) {
} final String newValue = command.stringValueOfParameterNamed(nameParamName);
actualChanges.put(nameParamName, newValue);
this.name = newValue;
}
this.parent = newParent; final String externalIdParamName = "externalId";
generateHierarchy(); if (command.isChangeInStringParameterNamed(externalIdParamName, this.externalId)) {
} final String newValue = command.stringValueOfParameterNamed(externalIdParamName);
actualChanges.put(externalIdParamName, newValue);
this.externalId = StringUtils.defaultIfEmpty(newValue, null);
}
public boolean identifiedBy(final Long id) { return actualChanges;
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() { private LocalDate getOpeningLocalDate() {
return hierarchy; LocalDate openingLocalDate = null;
} if (this.openingDate != null) {
openingLocalDate = LocalDate.fromDateFields(this.openingDate);
}
return openingLocalDate;
}
public boolean hasParentOf(final Office office) { public void update(final Office newParent) {
boolean isParent = false;
if (this.parent != null) {
isParent = this.parent.equals(office);
}
return isParent;
}
public boolean doesNotHaveAnOfficeInHierarchyWithId(Long officeId) { if (this.parent == null) { throw new RootOfficeParentCannotBeUpdated(); }
return !this.hasAnOfficeInHierarchyWithId(officeId);
}
private boolean hasAnOfficeInHierarchyWithId(Long officeId) { if (this.identifiedBy(newParent.getId())) { throw new CannotUpdateOfficeWithParentOfficeSameAsSelf(this.getId(), newParent.getId()); }
boolean match = false; this.parent = newParent;
generateHierarchy();
}
if (identifiedBy(officeId)) { public boolean identifiedBy(final Long id) {
match = true; return getId().equals(id);
} }
if (!match) { public void generateHierarchy() {
for (Office child : this.children) {
boolean result = child.hasAnOfficeInHierarchyWithId(officeId);
if (result) { if (parent != null) {
match = result; this.hierarchy = this.parent.hierarchyOf(this.getId());
break; } else {
} this.hierarchy = ".";
} }
} }
return match; 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 javax.persistence.TemporalType;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.organisation.monetary.domain.Money;
@@ -23,53 +24,54 @@ import org.mifosplatform.useradministration.domain.AppUser;
@Table(name = "m_office_transaction") @Table(name = "m_office_transaction")
public class OfficeTransaction extends AbstractAuditableCustom<AppUser, Long> { public class OfficeTransaction extends AbstractAuditableCustom<AppUser, Long> {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "from_office_id") @JoinColumn(name = "from_office_id")
private Office from; private Office from;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "to_office_id") @JoinColumn(name = "to_office_id")
private Office to; private Office to;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Column(name = "transaction_date", nullable = false) @Column(name = "transaction_date", nullable = false)
@Temporal(TemporalType.DATE) @Temporal(TemporalType.DATE)
private Date transactionDate; private Date transactionDate;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Embedded @Embedded
private MonetaryCurrency currency; private MonetaryCurrency currency;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Column(name = "transaction_amount", scale = 6, precision = 19, nullable = false) @Column(name = "transaction_amount", scale = 6, precision = 19, nullable = false)
private BigDecimal transactionAmount; private BigDecimal transactionAmount;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Column(name = "description", nullable=true, length=100) @Column(name = "description", nullable = true, length = 100)
private String description; private String description;
protected OfficeTransaction() { public static OfficeTransaction fromJson(final Office fromOffice, final Office toOffice, final Money amount, final JsonCommand command) {
this.transactionDate = null;
}
public static OfficeTransaction create(Office fromOffice, Office toOffice, LocalDate transactionLocalDate, Money amount, String description) { final LocalDate transactionLocalDate = command.localDateValueOfParameterNamed("transactionDate");
final String description = command.stringValueOfParameterNamed("description");
Date transactionDate = null; return new OfficeTransaction(fromOffice, toOffice, transactionLocalDate, amount, description);
if (transactionLocalDate != null) { }
transactionDate = transactionLocalDate.toDate();
}
return new OfficeTransaction(fromOffice, toOffice, transactionDate, amount, description); protected OfficeTransaction() {
} this.transactionDate = null;
}
private OfficeTransaction(final Office fromOffice,final Office toOffice, final Date transactionDate, final Money amount, String description) { private OfficeTransaction(final Office fromOffice, final Office toOffice, final LocalDate transactionLocalDate, final Money amount,
this.from = fromOffice; final String description) {
this.to = toOffice; this.from = fromOffice;
this.transactionDate = transactionDate; this.to = toOffice;
this.currency = amount.getCurrency(); if (transactionLocalDate != null) {
this.transactionAmount = amount.getAmount(); this.transactionDate = transactionLocalDate.toDate();
this.description = description; }
} 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.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; 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.AbstractFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer; import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.office.command.BranchMoneyTransferCommand; import org.mifosplatform.organisation.office.command.BranchMoneyTransferCommand;
@@ -35,33 +36,28 @@ public final class BranchMoneyTransferCommandFromApiJsonDeserializer extends Abs
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
@Autowired @Autowired
public BranchMoneyTransferCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper, public BranchMoneyTransferCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
final CommandSerializer commandSerializerService) {
super(commandSerializerService);
this.fromApiJsonHelper = fromApiJsonHelper; this.fromApiJsonHelper = fromApiJsonHelper;
} }
@Override @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(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final Set<String> parametersPassedInRequest = new HashSet<String>();
final JsonElement element = fromApiJsonHelper.parse(json); final JsonElement element = fromApiJsonHelper.parse(json);
final Long fromOfficeId = fromApiJsonHelper.extractLongNamed("fromOfficeId", element, parametersPassedInRequest); final Long fromOfficeId = fromApiJsonHelper.extractLongNamed("fromOfficeId", element);
final Long toOfficeId = fromApiJsonHelper.extractLongNamed("toOfficeId", element, parametersPassedInRequest); final Long toOfficeId = fromApiJsonHelper.extractLongNamed("toOfficeId", element);
final LocalDate transactionLocalDate = fromApiJsonHelper.extractLocalDateNamed("transactionDate", element, final LocalDate transactionLocalDate = fromApiJsonHelper.extractLocalDateNamed("transactionDate", element);
parametersPassedInRequest);
final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element, parametersPassedInRequest); final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element);
final BigDecimal transactionAmountValue = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("transactionAmount", element, final BigDecimal transactionAmountValue = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("transactionAmount", element);
parametersPassedInRequest); final String description = fromApiJsonHelper.extractStringNamed("description", element);
final String description = fromApiJsonHelper.extractStringNamed("description", element, parametersPassedInRequest);
return new BranchMoneyTransferCommand(parametersPassedInRequest, false, fromOfficeId, toOfficeId, transactionLocalDate, return new BranchMoneyTransferCommand(fromOfficeId, toOfficeId, transactionLocalDate, currencyCode, transactionAmountValue,
currencyCode, transactionAmountValue, description); 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.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; 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.AbstractFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer; import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.office.command.OfficeCommand; import org.mifosplatform.organisation.office.command.OfficeCommand;
@@ -28,31 +29,29 @@ public final class OfficeCommandFromApiJsonDeserializer extends AbstractFromApiJ
/** /**
* The parameters supported for this command. * 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; private final FromJsonHelper fromApiJsonHelper;
@Autowired @Autowired
public OfficeCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper, final CommandSerializer commandSerializerService) { public OfficeCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
super(commandSerializerService);
this.fromApiJsonHelper = fromApiJsonHelper; this.fromApiJsonHelper = fromApiJsonHelper;
} }
@Override @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(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final Set<String> parametersPassedInRequest = new HashSet<String>();
final JsonElement element = fromApiJsonHelper.parse(json); final JsonElement element = fromApiJsonHelper.parse(json);
final String name = fromApiJsonHelper.extractStringNamed("name", element, parametersPassedInRequest); final String name = fromApiJsonHelper.extractStringNamed("name", element);
final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element, parametersPassedInRequest); final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element);
final Long parentId = fromApiJsonHelper.extractLongNamed("parentId", element, parametersPassedInRequest); final Long parentId = fromApiJsonHelper.extractLongNamed("parentId", element);
final LocalDate openingLocalDate = fromApiJsonHelper.extractLocalDateNamed("openingDate", element, parametersPassedInRequest); 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; package org.mifosplatform.organisation.office.service;
import org.mifosplatform.organisation.office.command.BranchMoneyTransferCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.organisation.office.command.OfficeCommand; import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
public interface OfficeWritePlatformService { 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; 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.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.security.exception.NoAuthorizationException; import org.mifosplatform.infrastructure.security.exception.NoAuthorizationException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; 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.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.organisation.monetary.exception.CurrencyNotFoundException; 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.BranchMoneyTransferCommand;
import org.mifosplatform.organisation.office.command.OfficeCommand; import org.mifosplatform.organisation.office.command.OfficeCommand;
import org.mifosplatform.organisation.office.domain.Office; 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.OfficeTransaction;
import org.mifosplatform.organisation.office.domain.OfficeTransactionRepository; import org.mifosplatform.organisation.office.domain.OfficeTransactionRepository;
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException; 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.mifosplatform.useradministration.domain.AppUser;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -31,33 +35,39 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP
private final static Logger logger = LoggerFactory.getLogger(OfficeWritePlatformServiceJpaRepositoryImpl.class); private final static Logger logger = LoggerFactory.getLogger(OfficeWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final OfficeCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final BranchMoneyTransferCommandFromApiJsonDeserializer moneyTransferCommandFromApiJsonDeserializer;
private final OfficeRepository officeRepository; private final OfficeRepository officeRepository;
private final OfficeTransactionRepository officeMonetaryTransferRepository; private final OfficeTransactionRepository officeMonetaryTransferRepository;
private final ApplicationCurrencyRepository applicationCurrencyRepository; private final ApplicationCurrencyRepository applicationCurrencyRepository;
private final ConfigurationDomainService configurationDomainService;
@Autowired @Autowired
public OfficeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final OfficeRepository officeRepository, public OfficeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final OfficeTransactionRepository officeMonetaryTransferRepository, final OfficeCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final ApplicationCurrencyRepository applicationCurrencyRepository, final ConfigurationDomainService configurationDomainService) { final BranchMoneyTransferCommandFromApiJsonDeserializer moneyTransferCommandFromApiJsonDeserializer,
final OfficeRepository officeRepository, final OfficeTransactionRepository officeMonetaryTransferRepository,
final ApplicationCurrencyRepository applicationCurrencyRepository) {
this.context = context; this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.moneyTransferCommandFromApiJsonDeserializer = moneyTransferCommandFromApiJsonDeserializer;
this.officeRepository = officeRepository; this.officeRepository = officeRepository;
this.officeMonetaryTransferRepository = officeMonetaryTransferRepository; this.officeMonetaryTransferRepository = officeMonetaryTransferRepository;
this.applicationCurrencyRepository = applicationCurrencyRepository; this.applicationCurrencyRepository = applicationCurrencyRepository;
this.configurationDomainService = configurationDomainService;
} }
@Transactional @Transactional
@Override @Override
public Long createOffice(final OfficeCommand command) { public EntityIdentifier createOffice(final JsonCommand command) {
try { try {
final AppUser currentUser = context.authenticatedUser(); 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 // pre save to generate id for use in office hierarchy
this.officeRepository.save(office); this.officeRepository.save(office);
@@ -66,90 +76,94 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP
this.officeRepository.save(office); this.officeRepository.save(office);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("CREATE_OFFICE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } return EntityIdentifier.resourceResult(office.getId(), null);
return office.getId();
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
handleOfficeDataIntegrityIssues(command, dve); handleOfficeDataIntegrityIssues(command, dve);
return Long.valueOf(-1); return EntityIdentifier.empty();
} }
} }
@Transactional @Transactional
@Override @Override
public Long updateOffice(final OfficeCommand command) { public EntityIdentifier updateOffice(final Long officeId, final JsonCommand command) {
try { try {
final AppUser currentUser = context.authenticatedUser(); 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 Map<String, Object> changes = office.update(command);
final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getParentId());
if (changes.containsKey("parentId")) {
final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, officeCommand.getParentId());
office.update(parent); 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 EntityIdentifier.withChanges(office.getId(), changes);
return office.getId();
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
handleOfficeDataIntegrityIssues(command, dve); handleOfficeDataIntegrityIssues(command, dve);
return Long.valueOf(-1); return EntityIdentifier.empty();
} }
} }
@Transactional @Transactional
@Override @Override
public Long externalBranchMoneyTransfer(final BranchMoneyTransferCommand command) { public EntityIdentifier externalBranchMoneyTransfer(final JsonCommand command) {
context.authenticatedUser(); context.authenticatedUser();
command.validateBranchTransfer();
final BranchMoneyTransferCommand moneyTransferCommand = this.moneyTransferCommandFromApiJsonDeserializer.commandFromApiJson(command
.json());
moneyTransferCommand.validateBranchTransfer();
Office fromOffice = null; Office fromOffice = null;
if (command.getFromOfficeId() != null) { if (moneyTransferCommand.getFromOfficeId() != null) {
fromOffice = this.officeRepository.findOne(command.getFromOfficeId()); fromOffice = this.officeRepository.findOne(moneyTransferCommand.getFromOfficeId());
} }
Office toOffice = null; Office toOffice = null;
if (command.getToOfficeId() != null) { if (moneyTransferCommand.getToOfficeId() != null) {
toOffice = this.officeRepository.findOne(command.getToOfficeId()); 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); final ApplicationCurrency appCurrency = this.applicationCurrencyRepository.findOneByCode(currencyCode);
if (appCurrency == null) { throw new CurrencyNotFoundException(currencyCode); } if (appCurrency == null) { throw new CurrencyNotFoundException(currencyCode); }
final MonetaryCurrency currency = new MonetaryCurrency(appCurrency.getCode(), appCurrency.getDecimalPlaces()); 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, final OfficeTransaction entity = OfficeTransaction.fromJson(fromOffice, toOffice, amount, command);
command.getDescription());
this.officeMonetaryTransferRepository.save(entity); this.officeMonetaryTransferRepository.save(entity);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("CREATE_OFFICETRANSACTION") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } return EntityIdentifier.resourceResult(entity.getId(), null);
return entity.getId();
} }
/* /*
* Guaranteed to throw an exception no matter what the data integrity issue * Guaranteed to throw an exception no matter what the data integrity issue
* is. * is.
*/ */
private void handleOfficeDataIntegrityIssues(final OfficeCommand command, DataIntegrityViolationException dve) { private void handleOfficeDataIntegrityIssues(final JsonCommand command, DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause(); Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("externalid_org")) { if (realCause.getMessage().contains("externalid_org")) {
throw new PlatformDataIntegrityException("error.msg.office.duplicate.externalId", "Office with externalId {0} already exists", final String externalId = command.stringValueOfParameterNamed("externalId");
"externalId", command.getExternalId()); throw new PlatformDataIntegrityException("error.msg.office.duplicate.externalId", "Office with externalId `" + externalId
} else if (realCause.getMessage().contains("name_org")) { throw new PlatformDataIntegrityException( + "` already exists", "externalId", externalId);
"error.msg.office.duplicate.name", "Office with name {0} already exists", "name", command.getName()); } } 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); logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.office.unknown.data.integrity.issue", 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 * used to restrict modifying operations to office that are either the users
* office or lower (child) in the office hierarchy * 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()); final Long userOfficeId = currentUser.getOffice().getId();
if (userOffice == null) { throw new OfficeNotFoundException(currentUser.getOffice().getId()); } final Office userOffice = this.officeRepository.findOne(userOfficeId);
if (userOffice == null) { throw new OfficeNotFoundException(userOfficeId); }
if (userOffice.doesNotHaveAnOfficeInHierarchyWithId(officeId)) { throw new NoAuthorizationException( if (userOffice.doesNotHaveAnOfficeInHierarchyWithId(officeId)) { throw new NoAuthorizationException(
"User does not have sufficient priviledges to act on the provided office."); } "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.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
@@ -20,7 +19,6 @@ import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; 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.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier; import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; 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.data.OfficeLookup;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService; import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.organisation.staff.serialization.StaffCommandFromApiJsonDeserializer;
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService; import org.mifosplatform.organisation.staff.service.StaffReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
@@ -41,7 +38,8 @@ import org.springframework.stereotype.Component;
public class StaffApiResource { 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", private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "firstname", "lastname", "displayName",
"officeId", "officeName", "loanOfficerFlag", "allowedOffices")); "officeId", "officeName", "loanOfficerFlag", "allowedOffices"));
@@ -51,20 +49,18 @@ public class StaffApiResource {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final StaffReadPlatformService readPlatformService; private final StaffReadPlatformService readPlatformService;
private final OfficeReadPlatformService officeReadPlatformService; private final OfficeReadPlatformService officeReadPlatformService;
private final StaffCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<StaffData> toApiJsonSerializer; private final DefaultToApiJsonSerializer<StaffData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper; private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired @Autowired
public StaffApiResource(final PlatformSecurityContext context, final StaffReadPlatformService readPlatformService, public StaffApiResource(final PlatformSecurityContext context, final StaffReadPlatformService readPlatformService,
final OfficeReadPlatformService officeReadPlatformService, final StaffCommandFromApiJsonDeserializer fromApiJsonDeserializer, final OfficeReadPlatformService officeReadPlatformService, final DefaultToApiJsonSerializer<StaffData> toApiJsonSerializer,
final DefaultToApiJsonSerializer<StaffData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context; this.context = context;
this.readPlatformService = readPlatformService; this.readPlatformService = readPlatformService;
this.officeReadPlatformService = officeReadPlatformService; this.officeReadPlatformService = officeReadPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer; this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper; this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -90,13 +86,8 @@ public class StaffApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String createStaff(final String apiRequestBodyAsJson) { public String createStaff(final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "CREATE_STAFF"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_STAFF", "CREATE", "staff", null,
context.authenticatedUser().validateHasPermissionTo("CREATE_STAFF", allowedPermissions); apiRequestBodyAsJson);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "staff", null,
commandSerializedAsJson);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -126,13 +117,8 @@ public class StaffApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateStaff(@PathParam("staffId") final Long staffId, final String apiRequestBodyAsJson) { 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"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_STAFF", "UPDATE", "staff",
context.authenticatedUser().validateHasPermissionTo("UPDATE_STAFF", allowedPermissions); staffId, apiRequestBodyAsJson);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(staffId, apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "staff", staffId,
commandSerializedAsJson);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -2,7 +2,6 @@ package org.mifosplatform.organisation.staff.command;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set;
import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
@@ -18,61 +17,13 @@ public class StaffCommand {
private final Long officeId; private final Long officeId;
private final Boolean isLoanOfficer; private final Boolean isLoanOfficer;
private final transient Set<String> parametersPassedInRequest; public StaffCommand(final Long officeId, final String firstName, final String lastName, final Boolean isLoanOfficer) {
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;
this.firstname = firstName; this.firstname = firstName;
this.lastname = lastName; this.lastname = lastName;
this.officeId = officeId; this.officeId = officeId;
this.isLoanOfficer = isLoanOfficer; 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() { public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
@@ -91,7 +42,6 @@ public class StaffCommand {
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("staff"); 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("officeId").value(this.officeId).ignoreIfNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("firstname").value(this.firstname).ignoreIfNull().notBlank().notExceedingLengthOf(50); baseDataValidator.reset().parameter("firstname").value(this.firstname).ignoreIfNull().notBlank().notExceedingLengthOf(50);
baseDataValidator.reset().parameter("lastname").value(this.lastname).ignoreIfNull().notBlank().notExceedingLengthOf(50); baseDataValidator.reset().parameter("lastname").value(this.lastname).ignoreIfNull().notBlank().notExceedingLengthOf(50);
@@ -1,5 +1,8 @@
package org.mifosplatform.organisation.staff.domain; package org.mifosplatform.organisation.staff.domain;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
@@ -8,9 +11,9 @@ import javax.persistence.Table;
import javax.persistence.UniqueConstraint; import javax.persistence.UniqueConstraint;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.staff.command.StaffCommand;
import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.domain.AppUser;
@Entity @Entity
@@ -28,7 +31,6 @@ public class Staff extends AbstractAuditableCustom<AppUser, Long> {
private String displayName; private String displayName;
// Office to which this employee belongs // Office to which this employee belongs
@SuppressWarnings("unused")
@ManyToOne @ManyToOne
@JoinColumn(name = "office_id", nullable = false) @JoinColumn(name = "office_id", nullable = false)
private Office office; private Office office;
@@ -37,6 +39,20 @@ public class Staff extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "is_loan_officer ", nullable = false) @Column(name = "is_loan_officer ", nullable = false)
private boolean loanOfficer; 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) { public static Staff createNew(Office staffOffice, final String firstname, final String lastname, boolean isLoanOfficer) {
return new Staff(staffOffice, firstname, lastname, isLoanOfficer); return new Staff(staffOffice, firstname, lastname, isLoanOfficer);
} }
@@ -53,26 +69,50 @@ public class Staff extends AbstractAuditableCustom<AppUser, Long> {
deriveDisplayName(firstname); deriveDisplayName(firstname);
} }
public void update(final StaffCommand command, final Office staffOffice) { public void changeOffice(final Office newOffice) {
if (command.isOfficeChanged()) { this.office = newOffice;
this.office = staffOffice; }
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);
} }
if (command.isFirstnameChanged()) { boolean firstnameChanged = false;
this.firstname = StringUtils.defaultIfEmpty(command.getFirstname(), null); 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;
} }
if (command.isLastnameChanged()) { boolean lastnameChanged = false;
this.lastname = StringUtils.defaultIfEmpty(command.getLastname(), null); 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 (command.isLastnameChanged() || command.isFirstnameChanged()) { if (firstnameChanged || lastnameChanged) {
deriveDisplayName(firstname); deriveDisplayName(this.firstname);
} }
if (command.isLoanOfficerFlagChanged()) { final String isLoanOfficerParamName = "isLoanOfficer";
this.loanOfficer = command.getIsLoanOfficer(); if (command.isChangeInBooleanParameterNamed(isLoanOfficerParamName, this.loanOfficer)) {
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(isLoanOfficerParamName);
actualChanges.put(isLoanOfficerParamName, newValue);
this.loanOfficer = newValue;
} }
return actualChanges;
} }
public boolean isNotLoanOfficer() { public boolean isNotLoanOfficer() {
@@ -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.Map;
import java.util.Set; 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.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.staff.command.StaffCommand; import org.mifosplatform.organisation.staff.command.StaffCommand;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
/** /**
* Implementation of {@link FromApiJsonDeserializer} for {@link StaffCommand}'s. * Implementation of {@link FromApiJsonDeserializer} for {@link StaffCommand}'s.
*/ */
@Component @Component
public final class StaffCommandFromApiJsonDeserializer implements FromApiJsonDeserializer<StaffCommand> { public final class StaffCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<StaffCommand> {
/** /**
* The parameters supported for this command. * 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 Set<String> supportedParameters = new HashSet<String>(Arrays.asList("firstname", "lastname", "officeId", "isLoanOfficer"));
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
private final StaffCommandFromCommandJsonDeserializer fromCommandJsonDeserializer;
private final CommandSerializer commandSerializerService;
@Autowired @Autowired
public StaffCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper, public StaffCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
final StaffCommandFromCommandJsonDeserializer fromCommandJsonDeserializer,
final CommandSerializer commandSerializerService) {
this.fromApiJsonHelper = fromApiJsonHelper; this.fromApiJsonHelper = fromApiJsonHelper;
this.fromCommandJsonDeserializer = fromCommandJsonDeserializer;
this.commandSerializerService = commandSerializerService;
} }
@Override @Override
public StaffCommand commandFromApiJson(final String json) { public StaffCommand commandFromApiJson(final String json) {
return commandFromApiJson(null, json); if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
}
@Override
public StaffCommand commandFromApiJson(final Long roleId, final String json) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
return this.fromCommandJsonDeserializer.commandFromCommandJson(roleId, json); final JsonElement element = fromApiJsonHelper.parse(json);
}
@Override final String firstname = fromApiJsonHelper.extractStringNamed("firstname", element);
public String serializedCommandJsonFromApiJson(final String json) { final String lastname = fromApiJsonHelper.extractStringNamed("lastname", element);
final StaffCommand command = commandFromApiJson(json); final Boolean isLoanOfficer = fromApiJsonHelper.extractBooleanNamed("isLoanOfficer", element);
return this.commandSerializerService.serializeCommandToJson(command); final Long officeId = fromApiJsonHelper.extractLongNamed("officeId", element);
}
@Override return new StaffCommand(officeId, firstname, lastname, isLoanOfficer);
public String serializedCommandJsonFromApiJson(final Long roleId, final String json) {
final StaffCommand command = commandFromApiJson(roleId, json);
return this.commandSerializerService.serializeCommandToJson(command);
} }
} }
@@ -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; 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 { 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; package org.mifosplatform.organisation.staff.service;
import java.util.Map;
import org.apache.commons.lang.StringUtils; 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.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; 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.Office;
import org.mifosplatform.organisation.office.domain.OfficeRepository; import org.mifosplatform.organisation.office.domain.OfficeRepository;
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException; 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.Staff;
import org.mifosplatform.organisation.staff.domain.StaffRepository; import org.mifosplatform.organisation.staff.domain.StaffRepository;
import org.mifosplatform.organisation.staff.exception.StaffNotFoundException; 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; 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 static Logger logger = LoggerFactory.getLogger(StaffWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final StaffCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final StaffRepository staffRepository; private final StaffRepository staffRepository;
private final OfficeRepository officeRepository; private final OfficeRepository officeRepository;
private final ConfigurationDomainService configurationDomainService;
@Autowired @Autowired
public StaffWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final StaffRepository staffRepository, public StaffWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final OfficeRepository officeRepository, final ConfigurationDomainService configurationDomainService) { final StaffCommandFromApiJsonDeserializer fromApiJsonDeserializer, final StaffRepository staffRepository,
final OfficeRepository officeRepository) {
this.context = context; this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.staffRepository = staffRepository; this.staffRepository = staffRepository;
this.officeRepository = officeRepository; this.officeRepository = officeRepository;
this.configurationDomainService = configurationDomainService;
} }
@Transactional @Transactional
@Override @Override
public Long createStaff(final StaffCommand command) { public EntityIdentifier createStaff(final JsonCommand command) {
try { try {
context.authenticatedUser(); context.authenticatedUser();
command.validateForCreate();
final Office staffOffice = this.officeRepository.findOne(command.getOfficeId()); final StaffCommand staffCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
if (staffOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); } 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); this.staffRepository.save(staff);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("CREATE_STAFF") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } return EntityIdentifier.resourceResult(staff.getId(), null);
return staff.getId();
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
handleStaffDataIntegrityIssues(command, dve); handleStaffDataIntegrityIssues(command, dve);
return Long.valueOf(-1); return EntityIdentifier.empty();
} }
} }
@Transactional @Transactional
@Override @Override
public Long updateStaff(final StaffCommand command) { public EntityIdentifier updateStaff(final Long staffId, final JsonCommand command) {
try { try {
context.authenticatedUser(); context.authenticatedUser();
command.validateForUpdate();
final Long staffId = command.getId(); final StaffCommand staffCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
Staff staff = this.staffRepository.findOne(staffId); staffCommand.validateForUpdate();
if (staff == null) { throw new StaffNotFoundException(staffId); }
Office staffOffice = null; Staff staffForUpdate = this.staffRepository.findOne(staffId);
Long officeId = command.getOfficeId(); if (staffForUpdate == null) { throw new StaffNotFoundException(staffId); }
if (command.isOfficeChanged() && officeId != null) {
staffOffice = this.officeRepository.findOne(officeId); final Map<String, Object> changesOnly = staffForUpdate.update(command);
if (staffOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); }
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); return EntityIdentifier.withChanges(staffForUpdate.getId(), changesOnly);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("UPDATE_STAFF") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return staff.getId();
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
handleStaffDataIntegrityIssues(command, 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 * Guaranteed to throw an exception no matter what the data integrity issue
* is. * is.
*/ */
private void handleStaffDataIntegrityIssues(final StaffCommand command, DataIntegrityViolationException dve) { private void handleStaffDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause(); Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("display_name")) { if (realCause.getMessage().contains("display_name")) {
String displayName = command.getLastname(); final String lastname = command.stringValueOfParameterNamed("lastname");
if (!StringUtils.isBlank(command.getFirstname())) { String displayName = lastname;
displayName = command.getLastname() + ", " + command.getFirstname(); 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 '" throw new PlatformDataIntegrityException("error.msg.staff.duplicate.displayName", "A staff with the given display name '"
+ displayName + "' already exists", "displayName", displayName); + displayName + "' already exists", "displayName", displayName);
@@ -3,7 +3,6 @@ package org.mifosplatform.portfolio.charge.api;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import javax.ws.rs.Consumes; 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.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.charge.data.ChargeData; import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.charge.serialization.ChargeDefinitionCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService; import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
@@ -46,17 +44,14 @@ public class ChargesApiResource {
private final ChargeReadPlatformService readPlatformService; private final ChargeReadPlatformService readPlatformService;
private final DefaultToApiJsonSerializer<ChargeData> toApiJsonSerializer; private final DefaultToApiJsonSerializer<ChargeData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper; private final ApiRequestParameterHelper apiRequestParameterHelper;
private final ChargeDefinitionCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired @Autowired
public ChargesApiResource(final PlatformSecurityContext context, final ChargeReadPlatformService readPlatformService, public ChargesApiResource(final PlatformSecurityContext context, final ChargeReadPlatformService readPlatformService,
final ChargeDefinitionCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<ChargeData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, final DefaultToApiJsonSerializer<ChargeData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context; this.context = context;
this.readPlatformService = readPlatformService; this.readPlatformService = readPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer; this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper; this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -113,13 +108,8 @@ public class ChargesApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String createCharge(final String apiRequestBodyAsJson) { public String createCharge(final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "CREATE_CHARGE"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CHARGE", "CREATE", "charges", null,
context.authenticatedUser().validateHasPermissionTo("CREATE_CHARGE", allowedPermissions); apiRequestBodyAsJson);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "charges", null,
commandSerializedAsJson);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -130,14 +120,8 @@ public class ChargesApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateCharge(@PathParam("chargeId") final Long chargeId, final String apiRequestBodyAsJson) { 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"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CHARGE", "UPDATE", "charges", chargeId,
context.authenticatedUser().validateHasPermissionTo("UPDATE_CHARGE", allowedPermissions); apiRequestBodyAsJson);
final String commandSerializedAsJson = this.fromApiJsonDeserializer
.serializedCommandJsonFromApiJson(chargeId, apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "charges", chargeId,
commandSerializedAsJson);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -148,10 +132,7 @@ public class ChargesApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String deleteCharge(@PathParam("chargeId") final Long chargeId) { public String deleteCharge(@PathParam("chargeId") final Long chargeId) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "DELETE_CHARGE"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE_CHARGE", "DELETE", "charges", chargeId, "{}");
context.authenticatedUser().validateHasPermissionTo("DELETE_CHARGE", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "charges", chargeId, "{}");
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -3,7 +3,6 @@ package org.mifosplatform.portfolio.charge.command;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set;
import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
@@ -23,30 +22,18 @@ public class ChargeDefinitionCommand {
private final Boolean penalty; private final Boolean penalty;
private final Boolean active; private final Boolean active;
private final transient Set<String> parametersPassedInRequest; public ChargeDefinitionCommand(final String name, final BigDecimal amount, final String currencyCode, final Integer chargeTimeType,
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,
final Integer chargeAppliesTo, final Integer chargeCalculationType, final Boolean penalty, final Boolean active) { final Integer chargeAppliesTo, final Integer chargeCalculationType, final Boolean penalty, final Boolean active) {
this.makerCheckerApproval = makerCheckerApproval;
this.id = id;
this.name = name; this.name = name;
this.amount = amount; this.amount = amount;
this.currencyCode = currencyCode; this.currencyCode = currencyCode;
this.chargeTimeType = chargeTimeType; this.chargeTimeType = chargeTimeType;
this.chargeAppliesTo = chargeAppliesTo; this.chargeAppliesTo = chargeAppliesTo;
this.chargeCalculationType = chargeCalculationType; this.chargeCalculationType = chargeCalculationType;
this.parametersPassedInRequest = parametersPassedInRequest;
this.penalty = penalty; this.penalty = penalty;
this.active = active; this.active = active;
} }
public Long getId() {
return id;
}
public String getName() { public String getName() {
return name; return name;
} }
@@ -55,10 +42,6 @@ public class ChargeDefinitionCommand {
return amount; return amount;
} }
public Set<String> getModifiedParameters() {
return parametersPassedInRequest;
}
public String getCurrencyCode() { public String getCurrencyCode() {
return currencyCode; return currencyCode;
} }
@@ -87,42 +70,6 @@ public class ChargeDefinitionCommand {
return active; 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() { public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
@@ -148,10 +95,11 @@ public class ChargeDefinitionCommand {
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("charge"); 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("name").value(this.name).ignoreIfNull().notBlank().notExceedingLengthOf(100);
baseDataValidator.reset().parameter("amount").value(this.amount).ignoreIfNull().positiveAmount(); baseDataValidator.reset().parameter("amount").value(this.amount).ignoreIfNull().positiveAmount();
baseDataValidator.reset().parameter("currencyCode").value(this.currencyCode).ignoreIfNull().notBlank(); 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("chargeAppliesTo").value(this.chargeAppliesTo).ignoreIfNull().notNull().inMinMaxRange(1, 1);
baseDataValidator.reset().parameter("chargeTimeType").value(this.chargeTimeType).ignoreIfNull().notNull().inMinMaxRange(1, 2); baseDataValidator.reset().parameter("chargeTimeType").value(this.chargeTimeType).ignoreIfNull().notNull().inMinMaxRange(1, 2);
baseDataValidator.reset().parameter("chargeCalculationType").value(this.chargeCalculationType).ignoreIfNull().notNull() baseDataValidator.reset().parameter("chargeCalculationType").value(this.chargeCalculationType).ignoreIfNull().notNull()
@@ -1,11 +1,17 @@
package org.mifosplatform.portfolio.charge.domain; 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.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 @Entity
@Table(name = "m_charge", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "name") }) @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) @Column(name = "currency_code", length = 3)
private String currencyCode; private String currencyCode;
@SuppressWarnings("unused")
@Column(name = "charge_applies_to_enum", nullable = false) @Column(name = "charge_applies_to_enum", nullable = false)
private Integer chargeAppliesTo; private Integer chargeAppliesTo;
@@ -39,10 +44,21 @@ public class Charge extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "is_deleted", nullable = false) @Column(name = "is_deleted", nullable = false)
private boolean deleted = false; private boolean deleted = false;
public static Charge createNew(final String name, final BigDecimal amount, final String currencyCode, public static Charge fromJson(final JsonCommand command) {
final ChargeAppliesTo chargeAppliesTo, final ChargeTimeType chargeTime, final ChargeCalculationType chargeCalculationType,
final boolean penalty, final boolean active) { final String name = command.stringValueOfParameterNamed("name");
return new Charge(name, amount, currencyCode, chargeAppliesTo, chargeTime, chargeCalculationType, penalty, active); 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() { protected Charge() {
@@ -93,34 +109,73 @@ public class Charge extends AbstractAuditableCustom<AppUser, Long> {
return deleted; return deleted;
} }
public void update(final ChargeDefinitionCommand command) { public Map<String, Object> update(final JsonCommand command) {
if (command.isNameChanged()) {
this.name = command.getName(); 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()) { final String currencyCodeParamName = "currencyCode";
this.amount = command.getAmount(); if (command.isChangeInStringParameterNamed(currencyCodeParamName, this.currencyCode)) {
final String newValue = command.stringValueOfParameterNamed(currencyCodeParamName);
actualChanges.put(currencyCodeParamName, newValue);
this.currencyCode = newValue;
} }
if (command.isCurrencyCodeChanged()) { final String amountParamName = "amount";
this.currencyCode = command.getCurrencyCode(); 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()) { final String chargeTimeParamName = "chargeTime";
this.chargeTime = ChargeTimeType.fromInt(command.getChargeTimeType()).getValue(); 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()) { final String chargeAppliesToParamName = "chargeAppliesTo";
this.chargeAppliesTo = ChargeAppliesTo.fromInt(command.getChargeAppliesTo()).getValue(); 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()) { final String chargeCalculationParamName = "chargeCalculation";
this.chargeCalculation = ChargeCalculationType.fromInt(command.getChargeCalculationType()).getValue(); 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()) { final String penaltyParamName = "penalty";
this.active = command.isActive(); 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.Map;
import java.util.Set; 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.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.portfolio.charge.command.ChargeDefinitionCommand; 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. * Implementation of {@link FromApiJsonDeserializer} for {@link FundCommand}'s.
*/ */
@Component @Component
public final class ChargeDefinitionCommandFromApiJsonDeserializer implements FromApiJsonDeserializer<ChargeDefinitionCommand> { public final class ChargeDefinitionCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<ChargeDefinitionCommand> {
/** /**
* The parameters supported for this command. * The parameters supported for this command.
@@ -32,59 +34,33 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer implements Fro
"active")); "active"));
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
private final CommandSerializer commandSerializerService;
@Autowired @Autowired
public ChargeDefinitionCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper, public ChargeDefinitionCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
final CommandSerializer commandSerializerService) {
this.fromApiJsonHelper = fromApiJsonHelper; this.fromApiJsonHelper = fromApiJsonHelper;
this.commandSerializerService = commandSerializerService;
} }
@Override @Override
public ChargeDefinitionCommand commandFromApiJson(final String json) { public ChargeDefinitionCommand commandFromApiJson(final String json) {
return commandFromApiJson(null, json); if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
}
@Override
public ChargeDefinitionCommand commandFromApiJson(final Long chargeId, final String json) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final Set<String> parametersPassedInRequest = new HashSet<String>();
final JsonElement element = fromApiJsonHelper.parse(json); final JsonElement element = fromApiJsonHelper.parse(json);
final String name = fromApiJsonHelper.extractStringNamed("name", element, parametersPassedInRequest); final String name = fromApiJsonHelper.extractStringNamed("name", element);
final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element, parametersPassedInRequest); final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element);
final BigDecimal amount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("amount", element.getAsJsonObject(), final BigDecimal amount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("amount", element.getAsJsonObject());
parametersPassedInRequest);
final Integer chargeTimeType = fromApiJsonHelper final Integer chargeTimeType = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeTimeType", element);
.extractIntegerWithLocaleNamed("chargeTimeType", element, parametersPassedInRequest); final Integer chargeAppliesTo = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeAppliesTo", element);
final Integer chargeAppliesTo = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeAppliesTo", element, final Integer chargeCalculationType = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeCalculationType", element);
parametersPassedInRequest);
final Integer chargeCalculationType = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeCalculationType", element,
parametersPassedInRequest);
final Boolean penalty = fromApiJsonHelper.extractBooleanNamed("penalty", element, parametersPassedInRequest); final Boolean penalty = fromApiJsonHelper.extractBooleanNamed("penalty", element);
final Boolean active = fromApiJsonHelper.extractBooleanNamed("active", element, parametersPassedInRequest); final Boolean active = fromApiJsonHelper.extractBooleanNamed("active", element);
return new ChargeDefinitionCommand(parametersPassedInRequest, false, chargeId, name, amount, currencyCode, chargeTimeType, return new ChargeDefinitionCommand(name, amount, currencyCode, chargeTimeType, chargeAppliesTo, chargeCalculationType, penalty,
chargeAppliesTo, chargeCalculationType, penalty, active); 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);
} }
} }
@@ -1,12 +1,13 @@
package org.mifosplatform.portfolio.charge.service; 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 { 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; 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.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; 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.command.ChargeDefinitionCommand;
import org.mifosplatform.portfolio.charge.domain.Charge; 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.ChargeRepository;
import org.mifosplatform.portfolio.charge.domain.ChargeTimeType;
import org.mifosplatform.portfolio.charge.exception.ChargeNotFoundException; 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; 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 static Logger logger = LoggerFactory.getLogger(ChargeWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChargeDefinitionCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final ChargeRepository chargeRepository; private final ChargeRepository chargeRepository;
private final ConfigurationDomainService configurationDomainService;
@Autowired @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.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.chargeRepository = chargeRepository; this.chargeRepository = chargeRepository;
this.configurationDomainService = configurationDomainService;
} }
@Transactional @Transactional
@Override @Override
public Long createCharge(final ChargeDefinitionCommand command) { public EntityIdentifier createCharge(final JsonCommand command) {
try { try {
this.context.authenticatedUser(); this.context.authenticatedUser();
command.validateForCreate();
final ChargeAppliesTo chargeAppliesTo = ChargeAppliesTo.fromInt(command.getChargeAppliesTo()); final ChargeDefinitionCommand chargeDefinitionCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
final ChargeTimeType chargeTimeType = ChargeTimeType.fromInt(command.getChargeTimeType()); chargeDefinitionCommand.validateForCreate();
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 Charge charge = Charge.fromJson(command);
this.chargeRepository.save(charge); this.chargeRepository.save(charge);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("CREATE_CHARGE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } return EntityIdentifier.resourceResult(charge.getId(), null);
return charge.getId();
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve); handleDataIntegrityIssues(command, dve);
return Long.valueOf(-1); return EntityIdentifier.empty();
} }
} }
@Transactional @Transactional
@Override @Override
public Long updateCharge(final ChargeDefinitionCommand command) { public EntityIdentifier updateCharge(final Long chargeId, final JsonCommand command) {
try { try {
this.context.authenticatedUser(); this.context.authenticatedUser();
command.validateForUpdate();
final Long chargeId = command.getId(); final ChargeDefinitionCommand chargeDefinitionCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
chargeDefinitionCommand.validateForUpdate();
final Charge chargeForUpdate = this.chargeRepository.findOne(chargeId); final Charge chargeForUpdate = this.chargeRepository.findOne(chargeId);
if (chargeForUpdate == null) { throw new ChargeNotFoundException(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 EntityIdentifier.withChanges(chargeForUpdate.getId(), changes);
return chargeForUpdate.getId();
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve); handleDataIntegrityIssues(command, dve);
return Long.valueOf(-1); return EntityIdentifier.empty();
} }
} }
@Transactional @Transactional
@Override @Override
public Long deleteCharge(final ChargeDefinitionCommand command) { public EntityIdentifier deleteCharge(final Long chargeId) {
this.context.authenticatedUser(); this.context.authenticatedUser();
final Long chargeId = command.getId();
final Charge chargeForDelete = this.chargeRepository.findOne(chargeId); final Charge chargeForDelete = this.chargeRepository.findOne(chargeId);
if (chargeForDelete == null || chargeForDelete.isDeleted()) { throw new ChargeNotFoundException(chargeId); } if (chargeForDelete == null || chargeForDelete.isDeleted()) { throw new ChargeNotFoundException(chargeId); }
@@ -98,20 +94,20 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP
chargeRepository.save(chargeForDelete); chargeRepository.save(chargeForDelete);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("DELETE_CHARGE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } return EntityIdentifier.resourceResult(chargeForDelete.getId(), null);
return chargeForDelete.getId();
} }
/* /*
* Guaranteed to throw an exception no matter what the data integrity issue * Guaranteed to throw an exception no matter what the data integrity issue
* is. * is.
*/ */
private void handleDataIntegrityIssues(final ChargeDefinitionCommand command, final DataIntegrityViolationException dve) { private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause(); Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("name")) { throw new PlatformDataIntegrityException("error.msg.charge.duplicate.name", if (realCause.getMessage().contains("name")) {
"Charge with name {0} already exists", "name", command.getName()); } 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); logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.charge.unknown.data.integrity.issue", 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.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import javax.ws.rs.Consumes; 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.ClientData;
import org.mifosplatform.portfolio.client.data.ClientIdentifierData; import org.mifosplatform.portfolio.client.data.ClientIdentifierData;
import org.mifosplatform.portfolio.client.exception.DuplicateClientIdentifierException; import org.mifosplatform.portfolio.client.exception.DuplicateClientIdentifierException;
import org.mifosplatform.portfolio.client.serialization.ClientIdentifierCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
@@ -48,7 +46,6 @@ public class ClientIdentifiersApiResource {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ClientReadPlatformService clientReadPlatformService; private final ClientReadPlatformService clientReadPlatformService;
private final CodeValueReadPlatformService codeValueReadPlatformService; private final CodeValueReadPlatformService codeValueReadPlatformService;
private final ClientIdentifierCommandFromApiJsonDeserializer commandFromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<ClientIdentifierData> toApiJsonSerializer; private final DefaultToApiJsonSerializer<ClientIdentifierData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper; private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@@ -56,14 +53,12 @@ public class ClientIdentifiersApiResource {
@Autowired @Autowired
public ClientIdentifiersApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService, public ClientIdentifiersApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService,
final CodeValueReadPlatformService codeValueReadPlatformService, final CodeValueReadPlatformService codeValueReadPlatformService,
final ClientIdentifierCommandFromApiJsonDeserializer commandFromApiJsonDeserializer,
final DefaultToApiJsonSerializer<ClientIdentifierData> toApiJsonSerializer, final DefaultToApiJsonSerializer<ClientIdentifierData> toApiJsonSerializer,
final ApiRequestParameterHelper apiRequestParameterHelper, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context; this.context = context;
this.clientReadPlatformService = readPlatformService; this.clientReadPlatformService = readPlatformService;
this.codeValueReadPlatformService = codeValueReadPlatformService; this.codeValueReadPlatformService = codeValueReadPlatformService;
this.commandFromApiJsonDeserializer = commandFromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer; this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper; this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -103,16 +98,8 @@ public class ClientIdentifiersApiResource {
public String createClientIdentifier(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) { public String createClientIdentifier(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) {
try { try {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CLIENTIDENTIFIER", "CREATE",
"CREATE_CLIENTIDENTIFIER"); "clients", clientId, "identifiers", null, apiRequestBodyAsJson);
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);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} catch (DuplicateClientIdentifierException e) { } catch (DuplicateClientIdentifierException e) {
@@ -156,16 +143,8 @@ public class ClientIdentifiersApiResource {
@PathParam("identifierId") final Long clientIdentifierId, final String apiRequestBodyAsJson) { @PathParam("identifierId") final Long clientIdentifierId, final String apiRequestBodyAsJson) {
try { try {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CLIENTIDENTIFIER", "UPDATE",
"UPDATE_CLIENTIDENTIFIER"); "clients", clientId, "identifiers", clientIdentifierId, apiRequestBodyAsJson);
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);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} catch (DuplicateClientIdentifierException e) { } catch (DuplicateClientIdentifierException e) {
@@ -187,13 +166,8 @@ public class ClientIdentifiersApiResource {
public String deleteClientIdentifier(@PathParam("clientId") final Long clientId, public String deleteClientIdentifier(@PathParam("clientId") final Long clientId,
@PathParam("identifierId") final Long clientIdentifierId) { @PathParam("identifierId") final Long clientIdentifierId) {
final List<String> allowedPermissions = Arrays final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE_CLIENTIDENTIFIER", "DELETE",
.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "DELETE_CLIENTIDENTIFIER"); "clients", clientId, "identifiers", clientIdentifierId, "{}");
context.authenticatedUser().validateHasPermissionTo("DELETE_CLIENTIDENTIFIER", allowedPermissions);
final String resourceUrl = "clients/" + clientId + "/identifiers";
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", resourceUrl, clientIdentifierId,
"{}");
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -3,7 +3,6 @@ package org.mifosplatform.portfolio.client.api;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import javax.ws.rs.Consumes; 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.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.data.NoteData; import org.mifosplatform.portfolio.client.data.NoteData;
import org.mifosplatform.portfolio.client.serialization.ClientNoteCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
@@ -40,19 +38,16 @@ public class ClientNotesApiResource {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ClientReadPlatformService clientReadPlatformService; private final ClientReadPlatformService clientReadPlatformService;
private final ClientNoteCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<NoteData> toApiJsonSerializer; private final DefaultToApiJsonSerializer<NoteData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper; private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired @Autowired
public ClientNotesApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService, public ClientNotesApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService,
final ClientNoteCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<NoteData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, final DefaultToApiJsonSerializer<NoteData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context; this.context = context;
this.clientReadPlatformService = readPlatformService; this.clientReadPlatformService = readPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer; this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper; this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -76,14 +71,8 @@ public class ClientNotesApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String addNewClientNote(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) { 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"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CLIENTNOTE", "CREATE",
context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENTNOTE", allowedPermissions); "clients", clientId, "notes", null, apiRequestBodyAsJson);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJsonWithSubResource(apiRequestBodyAsJson, clientId);
final String resourceUrl = "clients/" + clientId + "/notes";
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", resourceUrl, null,
commandSerializedAsJson);
return this.toApiJsonSerializer.serialize(result); 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, public String updateClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId,
final String apiRequestBodyAsJson) { final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "UPDATE_CLIENTNOTE"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CLIENTNOTE", "UPDATE",
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENTNOTE", allowedPermissions); "clients", clientId, "notes", noteId, apiRequestBodyAsJson);
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);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -213,10 +213,7 @@ public class ClientsApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String createClient(final String apiRequestBodyAsJson) { public String createClient(final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "CREATE_CLIENT"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CLIENT", "CREATE", "clients", null,
context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENT", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "clients", null,
apiRequestBodyAsJson); apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
@@ -228,10 +225,7 @@ public class ClientsApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateClient(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) { 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"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CLIENT", "UPDATE", "clients", clientId,
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENT", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "clients", clientId,
apiRequestBodyAsJson); apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
@@ -243,10 +237,7 @@ public class ClientsApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String deleteClient(@PathParam("clientId") final Long clientId) { public String deleteClient(@PathParam("clientId") final Long clientId) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "DELETE_CLIENT"); final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE_CLIENT", "DELETE", "clients", clientId, "{}");
context.authenticatedUser().validateHasPermissionTo("DELETE_CLIENT", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "clients", clientId, "{}");
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -1,42 +1,27 @@
package org.mifosplatform.portfolio.client.command; 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. * Immutable command for creating or updating details of a client identifier.
*/ */
public class ClientIdentifierCommand { public class ClientIdentifierCommand {
private final Long clientId;
private final Long documentTypeId; private final Long documentTypeId;
private final String documentKey; private final String documentKey;
private final String description; private final String description;
private final transient Set<String> modifiedParameters; public ClientIdentifierCommand(final Long documentTypeId, final String documentKey, final String description) {
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;
this.documentTypeId = documentTypeId; this.documentTypeId = documentTypeId;
this.documentKey = documentKey; this.documentKey = documentKey;
this.description = description; this.description = description;
} }
public Long getId() {
return id;
}
public Long getDocumentTypeId() { public Long getDocumentTypeId() {
return documentTypeId; return documentTypeId;
} }
@@ -49,27 +34,33 @@ public class ClientIdentifierCommand {
return description; return description;
} }
public Set<String> getModifiedParameters() { public void validateForCreate() {
return modifiedParameters; List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("clientIdentifier");
baseDataValidator.reset().parameter("documentTypeId").value(this.documentTypeId).notNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("documentKey").value(this.documentKey).notBlank();
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
} }
public Long getClientId() { public void validateForUpdate() {
return clientId; List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
}
public boolean isDocumentTypeChanged() { DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("clientIdentifier");
return this.modifiedParameters.contains("documentTypeId");
}
public boolean isDocumentKeyChanged() { baseDataValidator.reset().parameter("documentKey").value(this.documentKey).ignoreIfNull().notBlank();
return this.modifiedParameters.contains("documentKey");
}
public boolean isDescriptionChanged() { // FIXME - kw
return this.modifiedParameters.contains("description"); // if (command.isDocumentTypeChanged()) {
} // baseDataValidator.reset().parameter("documentTypeId").value(command.getDocumentTypeId()).notNull().integerGreaterThanZero();
// }
public boolean isApprovedByChecker() { baseDataValidator.reset().anyOfNotNull(this.documentTypeId, this.documentKey);
return this.makerCheckerApproval;
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; package org.mifosplatform.portfolio.client.command;
import java.util.Set;
/** /**
* Immutable command used for create or update of notes. * Immutable command used for create or update of notes.
*/ */
public class ClientNoteCommand { public class ClientNoteCommand {
private final Long clientId;
private final String note; private final String note;
private final transient Long id; public ClientNoteCommand(final String note) {
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;
this.note = note; this.note = note;
} }
public Long getId() {
return id;
}
public Long getClientId() {
return clientId;
}
public String getNote() { public String getNote() {
return note; return note;
} }
@@ -135,6 +135,17 @@ public class Client extends AbstractAuditableCustom<AppUser, Long> {
this.joinedDate = newValue.toDate(); 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"; final String firstnameParamName = "firstname";
if (command.isChangeInStringParameterNamed(firstnameParamName, this.firstName)) { if (command.isChangeInStringParameterNamed(firstnameParamName, this.firstName)) {
final String newValue = command.stringValueOfParameterNamed(firstnameParamName); final String newValue = command.stringValueOfParameterNamed(firstnameParamName);
@@ -142,14 +153,7 @@ public class Client extends AbstractAuditableCustom<AppUser, Long> {
this.firstName = newValue; 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())) { if (command.isChangeInStringParameterNamed(clientOrBusinessNameParamName, getClientOrBusinessName())) {
final String newValue = command.stringValueOfParameterNamed(clientOrBusinessNameParamName); final String newValue = command.stringValueOfParameterNamed(clientOrBusinessNameParamName);
actualChanges.put(clientOrBusinessNameParamName, newValue); actualChanges.put(clientOrBusinessNameParamName, newValue);
@@ -184,6 +188,18 @@ public class Client extends AbstractAuditableCustom<AppUser, Long> {
return joiningLocalDate; 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() { private String getClientOrBusinessName() {
String clientOrBusinessName = null; String clientOrBusinessName = null;
if (StringUtils.isBlank(this.firstName) && StringUtils.isNotBlank(this.lastName)) { if (StringUtils.isBlank(this.firstName) && StringUtils.isNotBlank(this.lastName)) {

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