mifosx-97 still refactoring audit/makerchecker bits

This commit is contained in:
John Woodlock
2013-04-02 18:49:58 +01:00
parent ec810d9485
commit a9eb946ecd
3 changed files with 183 additions and 90 deletions
@@ -28,6 +28,7 @@ import org.mifosplatform.commands.data.AuditSearchData;
import org.mifosplatform.commands.data.CommandSourceData; import org.mifosplatform.commands.data.CommandSourceData;
import org.mifosplatform.commands.service.AuditReadPlatformService; import org.mifosplatform.commands.service.AuditReadPlatformService;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
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.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException; import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
@@ -44,45 +45,66 @@ import org.springframework.stereotype.Component;
public class MakercheckersApiResource { public class MakercheckersApiResource {
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>( private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList("id", "actionName", "entityName", "resourceId", "subresourceId", Arrays.asList("id", "actionName", "entityName", "resourceId",
"maker", "madeOnDate", "checker", "checkedOnDate", "processingResult", "subresourceId", "maker", "madeOnDate", "checker",
"commandAsJson", "officeName", "groupLevelName", "groupName", "clientName", "loanAccountNo", "savingsAccountNo")); "checkedOnDate", "processingResult", "commandAsJson",
private final String resourceNameForPermissions = "MAKERCHECKER"; "officeName", "groupLevelName", "groupName", "clientName",
"loanAccountNo", "savingsAccountNo"));
private final String resourceNameForPermissions = "MAKERCHECKER";
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final AuditReadPlatformService readPlatformService; private final AuditReadPlatformService readPlatformService;
private final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer; private final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer;
private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit; private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit;
private final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate; private final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate;
private final ApiRequestParameterHelper apiRequestParameterHelper; private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService writePlatformService; private final PortfolioCommandSourceWritePlatformService writePlatformService;
@Autowired @Autowired
public MakercheckersApiResource(final PlatformSecurityContext context, final AuditReadPlatformService readPlatformService, public MakercheckersApiResource(
final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer, final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit, final PlatformSecurityContext context,
final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate, final AuditReadPlatformService readPlatformService,
final ApiRequestParameterHelper apiRequestParameterHelper, final PortfolioCommandSourceWritePlatformService writePlatformService) { final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer,
this.context = context; final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit,
this.readPlatformService = readPlatformService; final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate,
this.toApiJsonSerializer = toApiJsonSerializer; final ApiRequestParameterHelper apiRequestParameterHelper,
this.apiRequestParameterHelper = apiRequestParameterHelper; final PortfolioCommandSourceWritePlatformService writePlatformService) {
this.toApiJsonSerializerAudit = toApiJsonSerializerAudit; this.context = context;
this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate; this.readPlatformService = readPlatformService;
this.writePlatformService = writePlatformService; this.toApiJsonSerializer = toApiJsonSerializer;
} this.apiRequestParameterHelper = apiRequestParameterHelper;
this.toApiJsonSerializerAudit = toApiJsonSerializerAudit;
this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate;
this.writePlatformService = writePlatformService;
}
@GET @GET
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveCommands(@Context final UriInfo uriInfo) { public String retrieveCommands(@Context final UriInfo uriInfo,
@QueryParam("actionName") final String actionName,
@QueryParam("entityName") final String entityName,
@QueryParam("resourceId") final Long resourceId,
@QueryParam("makerId") final Long makerId,
@QueryParam("makerDateTimeFrom") final String makerDateTimeFrom,
@QueryParam("makerDateTimeTo") final String makerDateTimeTo) {
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); context.authenticatedUser().validateHasReadPermission(
resourceNameForPermissions);
final Collection<AuditData> entries = this.readPlatformService.retrieveAllEntriesToBeChecked(); final String extraCriteria = getExtraCriteria(actionName, entityName,
resourceId, makerId, makerDateTimeFrom, makerDateTimeTo);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper
return this.toApiJsonSerializerAudit.serialize(settings, entries, RESPONSE_DATA_PARAMETERS); .process(uriInfo.getQueryParameters());
}
final Collection<AuditData> entries = this.readPlatformService
.retrieveAllEntriesToBeChecked(extraCriteria,
settings.isIncludeJson());
return this.toApiJsonSerializerAudit.serialize(settings, entries,
RESPONSE_DATA_PARAMETERS);
}
@GET @GET
@Path("/searchtemplate") @Path("/searchtemplate")
@@ -106,34 +128,76 @@ public class MakercheckersApiResource {
auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE); auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE);
} }
@POST @POST
@Path("{commandId}") @Path("{commandId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String approveMakerCheckerEntry(@PathParam("commandId") final Long commandId, @QueryParam("command") final String commandParam) { public String approveMakerCheckerEntry(
@PathParam("commandId") final Long commandId,
@QueryParam("command") final String commandParam) {
CommandProcessingResult result = null; CommandProcessingResult result = null;
if (is(commandParam, "approve")) { if (is(commandParam, "approve")) {
result = this.writePlatformService.approveEntry(commandId); result = this.writePlatformService.approveEntry(commandId);
} else { } else {
throw new UnrecognizedQueryParamException("command", commandParam); throw new UnrecognizedQueryParamException("command", commandParam);
} }
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
private boolean is(final String commandParam, final String commandValue) { private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue); return StringUtils.isNotBlank(commandParam)
} && commandParam.trim().equalsIgnoreCase(commandValue);
}
@DELETE @DELETE
@Path("{commandId}") @Path("{commandId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String deleteMakerCheckerEntry(@PathParam("commandId") final Long commandId) { public String deleteMakerCheckerEntry(
@PathParam("commandId") final Long commandId) {
final Long id = this.writePlatformService.deleteEntry(commandId); final Long id = this.writePlatformService.deleteEntry(commandId);
return this.toApiJsonSerializer.serialize(CommandProcessingResult.commandOnlyResult(id)); return this.toApiJsonSerializer.serialize(CommandProcessingResult
} .commandOnlyResult(id));
}
private String getExtraCriteria(final String actionName,
final String entityName, final Long resourceId, final Long makerId,
final String makerDateTimeFrom, final String makerDateTimeTo) {
String extraCriteria = "";
if (actionName != null) {
extraCriteria += " and aud.action_name = "
+ ApiParameterHelper.sqlEncodeString(actionName);
}
if (entityName != null) {
extraCriteria += " and aud.entity_name like "
+ ApiParameterHelper.sqlEncodeString(entityName + "%");
}
if (resourceId != null) {
extraCriteria += " and aud.resource_id = " + resourceId;
}
if (makerId != null) {
extraCriteria += " and aud.maker_id = " + makerId;
}
if (makerDateTimeFrom != null) {
extraCriteria += " and aud.made_on_date >= "
+ ApiParameterHelper.sqlEncodeString(makerDateTimeFrom);
}
if (makerDateTimeTo != null) {
extraCriteria += " and aud.made_on_date <= "
+ ApiParameterHelper.sqlEncodeString(makerDateTimeTo);
}
if (StringUtils.isNotBlank(extraCriteria)) {
extraCriteria = extraCriteria.substring(4);
}
return extraCriteria;
}
} }
@@ -14,10 +14,10 @@ public interface AuditReadPlatformService {
Collection<AuditData> retrieveAuditEntries(String extraCriteria, boolean includeJson); Collection<AuditData> retrieveAuditEntries(String extraCriteria, boolean includeJson);
Collection<AuditData> retrieveAllEntriesToBeChecked(String extraCriteria, boolean includeJson);
AuditData retrieveAuditEntry(Long auditId); AuditData retrieveAuditEntry(Long auditId);
AuditSearchData retrieveSearchTemplate(String useType); AuditSearchData retrieveSearchTemplate(String useType);
Collection<AuditData> retrieveAllEntriesToBeChecked();
} }
@@ -20,6 +20,7 @@ import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityExce
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.useradministration.data.AppUserData; import org.mifosplatform.useradministration.data.AppUserData;
import org.mifosplatform.useradministration.domain.AppUser;
import org.mifosplatform.useradministration.service.AppUserReadPlatformService; import org.mifosplatform.useradministration.service.AppUserReadPlatformService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -47,14 +48,14 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
} }
private static final class AuditMapper implements RowMapper<AuditData> { private static final class AuditMapper implements RowMapper<AuditData> {
//TODO - jpw need to break this down, also data scope etc.
public String schema(boolean includeJson) { public String schema(boolean includeJson, String hierarchy) {
String commandAsJsonString = ""; String commandAsJsonString = "";
if (includeJson) if (includeJson)
commandAsJsonString = ", aud.command_as_json as commandAsJson "; commandAsJsonString = ", aud.command_as_json as commandAsJson ";
return " aud.id as id, aud.action_name as actionName, aud.entity_name as entityName," String partSql = " aud.id as id, aud.action_name as actionName, aud.entity_name as entityName,"
+ " aud.resource_id as resourceId, aud.subresource_id as subresourceId," + " aud.resource_id as resourceId, aud.subresource_id as subresourceId,"
+ " mk.username as maker, aud.made_on_date as madeOnDate, " + " mk.username as maker, aud.made_on_date as madeOnDate, "
+ "ck.username as checker, aud.checked_on_date as checkedOnDate, ev.enum_message_property as processingResult " + "ck.username as checker, aud.checked_on_date as checkedOnDate, ev.enum_message_property as processingResult "
@@ -72,6 +73,15 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
+ " left join m_loan l on l.id = aud.loan_id" + " left join m_loan l on l.id = aud.loan_id"
+ " left join m_savings_account s on s.id = aud.savings_account_id" + " left join m_savings_account s on s.id = aud.savings_account_id"
+ " left join r_enum_value ev on ev.enum_name = 'processing_result_enum' and ev.enum_id = aud.processing_result_enum"; + " left join r_enum_value ev on ev.enum_name = 'processing_result_enum' and ev.enum_id = aud.processing_result_enum";
// data scoping: head office (hierarchy = ".") can see all audit
// entries
if (!(hierarchy.equals("."))) {
partSql += " join m_office o on o.id = aud.office_id and o.hierarchy like '"
+ hierarchy + "%' ";
}
return partSql;
} }
@Override @Override
@@ -117,25 +127,55 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
@Override @Override
public Collection<AuditData> retrieveAuditEntries(String extraCriteria, public Collection<AuditData> retrieveAuditEntries(String extraCriteria,
boolean includeJson) { boolean includeJson) {
context.authenticatedUser();
String updatedExtraCriteria = "";
if (StringUtils.isNotBlank(extraCriteria))
updatedExtraCriteria = " where (" + extraCriteria + ")";
updatedExtraCriteria += " order by aud.id DESC";
return retrieveEntries(updatedExtraCriteria, includeJson);
}
@Override
public Collection<AuditData> retrieveAllEntriesToBeChecked(
String extraCriteria, boolean includeJson) {
String updatedExtraCriteria = "";
if (StringUtils.isNotBlank(extraCriteria))
updatedExtraCriteria = " where (" + extraCriteria + ")"
+ " and aud.processing_result_enum = 2";
else
updatedExtraCriteria = " where aud.processing_result_enum = 2";
updatedExtraCriteria += " order by aud.id";
//TODO - should only be pulling back makerchecker entries that the user has maker-checker permissions for
return retrieveEntries(updatedExtraCriteria, includeJson);
}
public Collection<AuditData> retrieveEntries(String extraCriteria,
boolean includeJson) {
AppUser currentUser = context.authenticatedUser();
String hierarchy = currentUser.getOffice().getHierarchy();
final AuditMapper rm = new AuditMapper(); final AuditMapper rm = new AuditMapper();
String sql = "select " + rm.schema(includeJson); String sql = "select " + rm.schema(includeJson, hierarchy)
if (StringUtils.isNotBlank(extraCriteria)) + extraCriteria;
sql += " where (" + extraCriteria + ")";
sql += " order by aud.id DESC";
logger.info("sql: " + sql); logger.info("sql: " + sql);
return this.jdbcTemplate.query(sql, rm, new Object[] {}); return this.jdbcTemplate.query(sql, rm, new Object[] {});
} }
@Override @Override
public AuditData retrieveAuditEntry(Long auditId) { public AuditData retrieveAuditEntry(Long auditId) {
context.authenticatedUser();
AppUser currentUser = context.authenticatedUser();
String hierarchy = currentUser.getOffice().getHierarchy();
final AuditMapper rm = new AuditMapper(); final AuditMapper rm = new AuditMapper();
String sql = "select " + rm.schema(true); String sql = "select " + rm.schema(true, hierarchy);
sql += " where aud.id = " + auditId; sql += " where aud.id = " + auditId;
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {}); return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {});
@@ -144,9 +184,11 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
@Override @Override
public AuditSearchData retrieveSearchTemplate(String useType) { public AuditSearchData retrieveSearchTemplate(String useType) {
if (!(useType.equals("audit") || useType.equals("makerchecker"))) { if (!(useType.equals("audit") || useType.equals("makerchecker"))) {
throw new PlatformDataIntegrityException("error.msg.invalid.auditSearchTemplate.useType", throw new PlatformDataIntegrityException(
"Invalid Audit Search Template UseType: " + useType); } "error.msg.invalid.auditSearchTemplate.useType",
"Invalid Audit Search Template UseType: " + useType);
}
final Collection<AppUserData> appUsers = appUserReadPlatformService final Collection<AppUserData> appUsers = appUserReadPlatformService
.retrieveSearchTemplate(); .retrieveSearchTemplate();
@@ -162,27 +204,14 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
Collection<ProcessingResultLookup> processingResults = null; Collection<ProcessingResultLookup> processingResults = null;
if (useType.equals("audit")) { if (useType.equals("audit")) {
ProcessingResultsMapper mapper3 = new ProcessingResultsMapper(); ProcessingResultsMapper mapper3 = new ProcessingResultsMapper();
processingResults = this.jdbcTemplate.query(mapper3.schema(), mapper3, new Object[] {}); processingResults = this.jdbcTemplate.query(mapper3.schema(),
mapper3, new Object[] {});
} }
return new AuditSearchData(appUsers, actionNames, entityNames, return new AuditSearchData(appUsers, actionNames, entityNames,
processingResults); processingResults);
} }
@Override
public Collection<AuditData> retrieveAllEntriesToBeChecked() {
context.authenticatedUser();
final AuditMapper rm = new AuditMapper();
final String sql = "select " + rm.schema(false)
+ " where aud.checker_id is null and aud.processing_result_enum = 2 order by aud.id";
//+ " where mc.checker_id is null and mc.processing_result_enum = 2 order by mc.made_on_date DESC, mc.entity_name ASC, mc.action_name ASC";
logger.info("sql: " + sql);
return this.jdbcTemplate.query(sql, rm, new Object[] {});
}
private static final class ActionNamesMapper implements RowMapper<String> { private static final class ActionNamesMapper implements RowMapper<String> {
@Override @Override