mifosx-274 add id fields for datatables (to audit log)

This commit is contained in:
John Woodlock
2013-03-26 00:32:59 +00:00
parent d4a5b55e71
commit 82f97875a7
10 changed files with 200 additions and 114 deletions
@@ -289,7 +289,7 @@ CREATE TABLE `m_portfolio_command_source` (
`group_id` bigint(20) DEFAULT NULL, `group_id` bigint(20) DEFAULT NULL,
`client_id` bigint(20) DEFAULT NULL, `client_id` bigint(20) DEFAULT NULL,
`loan_id` bigint(20) DEFAULT NULL, `loan_id` bigint(20) DEFAULT NULL,
`savings_id` BIGINT(20) DEFAULT NULL, `savings_account_id` bigint(20) DEFAULT NULL,
`api_get_url` varchar(100) NOT NULL, `api_get_url` varchar(100) NOT NULL,
`resource_id` bigint(20) DEFAULT NULL, `resource_id` bigint(20) DEFAULT NULL,
`subresource_id` bigint(20) DEFAULT NULL, `subresource_id` bigint(20) DEFAULT NULL,
@@ -48,7 +48,7 @@ public class CommandSource extends AbstractPersistable<Long> {
private Long loanId; private Long loanId;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Column(name = "savings_id") @Column(name = "savings_account_id")
private Long savingsId; private Long savingsId;
@Column(name = "api_get_url", length = 100) @Column(name = "api_get_url", length = 100)
@@ -169,12 +169,12 @@ public class CommandSource extends AbstractPersistable<Long> {
this.processingResult = CommandProcessingResultType.AWAITING_APPROVAL.getValue(); this.processingResult = CommandProcessingResultType.AWAITING_APPROVAL.getValue();
} }
public void updateForAudit(final Long officeId, final Long groupId, final Long clientId, final Long loanId, final Long savignsId) { public void updateForAudit(final Long officeId, final Long groupId, final Long clientId, final Long loanId, final Long savingsId) {
this.officeId = officeId; this.officeId = officeId;
this.groupId = groupId; this.groupId = groupId;
this.clientId = clientId; this.clientId = clientId;
this.loanId = loanId; this.loanId = loanId;
this.savingsId = savignsId; this.savingsId = savingsId;
} }
public String getResourceGetUrl() { public String getResourceGetUrl() {
@@ -69,8 +69,7 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
commandSourceResult = CommandSource.fullEntryFrom(wrapper, command, maker); commandSourceResult = CommandSource.fullEntryFrom(wrapper, command, maker);
} }
commandSourceResult.updateResourceId(result.resourceId()); commandSourceResult.updateResourceId(result.resourceId());
commandSourceResult.updateForAudit(result.getOfficeId(), result.getGroupId(), result.getClientId(), result.getLoanId(), commandSourceResult.updateForAudit(result.getOfficeId(), result.getGroupId(), result.getClientId(), result.getLoanId(), result.getSavingsId());
result.getSavingsId());
String changesOnlyJson = null; String changesOnlyJson = null;
if (result.hasChanges()) { if (result.hasChanges()) {
@@ -28,11 +28,16 @@ public class CreateDatatableEntryCommandHandler implements NewCommandSourceHandl
@Override @Override
public CommandProcessingResult processCommand(final JsonCommand command) { public CommandProcessingResult processCommand(final JsonCommand command) {
this.writePlatformService.createNewDatatableEntry(command.entityName(), command.entityId(), command); CommandProcessingResult commandProcessingResult = this.writePlatformService.createNewDatatableEntry(command.entityName(), command.entityId(), command);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
.withEntityId(command.entityId()) // .withEntityId(command.entityId()) //
.withOfficeId(commandProcessingResult.getOfficeId()) //
.withGroupId(commandProcessingResult.getGroupId()) //
.withClientId(commandProcessingResult.getClientId()) //
.withSavingsId(commandProcessingResult.getSavingsId()) //
.withLoanId(commandProcessingResult.getLoanId()) //
.build(); .build();
} }
} }
@@ -28,8 +28,16 @@ public class DeleteOneToManyDatatableEntryCommandHandler implements NewCommandSo
@Override @Override
public CommandProcessingResult processCommand(final JsonCommand command) { public CommandProcessingResult processCommand(final JsonCommand command) {
this.writePlatformService.deleteDatatableEntry(command.entityName(), command.entityId(), command.subentityId()); CommandProcessingResult commandProcessingResult = this.writePlatformService.deleteDatatableEntry(command.entityName(), command.entityId(), command.subentityId());
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(command.entityId()).build(); return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(command.entityId()) //
.withOfficeId(commandProcessingResult.getOfficeId()) //
.withGroupId(commandProcessingResult.getGroupId()) //
.withClientId(commandProcessingResult.getClientId()) //
.withSavingsId(commandProcessingResult.getSavingsId()) //
.withLoanId(commandProcessingResult.getLoanId()) //
.build();
} }
} }
@@ -28,11 +28,16 @@ public class DeleteOneToOneDatatableEntryCommandHandler implements NewCommandSou
@Override @Override
public CommandProcessingResult processCommand(final JsonCommand command) { public CommandProcessingResult processCommand(final JsonCommand command) {
this.writePlatformService.deleteDatatableEntries(command.entityName(), command.entityId()); CommandProcessingResult commandProcessingResult = this.writePlatformService.deleteDatatableEntries(command.entityName(), command.entityId());
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
.withEntityId(command.entityId()) // .withEntityId(command.entityId()) //
.withOfficeId(commandProcessingResult.getOfficeId()) //
.withGroupId(commandProcessingResult.getGroupId()) //
.withClientId(commandProcessingResult.getClientId()) //
.withSavingsId(commandProcessingResult.getSavingsId()) //
.withLoanId(commandProcessingResult.getLoanId()) //
.build(); .build();
} }
} }
@@ -5,8 +5,6 @@
*/ */
package org.mifosplatform.infrastructure.dataqueries.handler; package org.mifosplatform.infrastructure.dataqueries.handler;
import java.util.Map;
import org.mifosplatform.commands.handler.NewCommandSourceHandler; import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
@@ -30,9 +28,18 @@ public class UpdateOneToManyDatatableEntryCommandHandler implements NewCommandSo
@Override @Override
public CommandProcessingResult processCommand(final JsonCommand command) { public CommandProcessingResult processCommand(final JsonCommand command) {
final Map<String, Object> changes = this.writePlatformService.updateDatatableEntryOneToMany(command.entityName(), final CommandProcessingResult commandProcessingResult = this.writePlatformService.updateDatatableEntryOneToMany(command.entityName(),
command.entityId(), command.subentityId(), command); command.entityId(), command.subentityId(), command);
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(command.entityId()).with(changes).build(); return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(command.entityId()) //
.withOfficeId(commandProcessingResult.getOfficeId()) //
.withGroupId(commandProcessingResult.getGroupId()) //
.withClientId(commandProcessingResult.getClientId()) //
.withSavingsId(commandProcessingResult.getSavingsId()) //
.withLoanId(commandProcessingResult.getLoanId()) //
.with(commandProcessingResult.getChanges()) //
.build();
} }
} }
@@ -5,8 +5,6 @@
*/ */
package org.mifosplatform.infrastructure.dataqueries.handler; package org.mifosplatform.infrastructure.dataqueries.handler;
import java.util.Map;
import org.mifosplatform.commands.handler.NewCommandSourceHandler; import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
@@ -30,13 +28,18 @@ public class UpdateOneToOneDatatableEntryCommandHandler implements NewCommandSou
@Override @Override
public CommandProcessingResult processCommand(final JsonCommand command) { public CommandProcessingResult processCommand(final JsonCommand command) {
final Map<String, Object> changes = this.writePlatformService.updateDatatableEntryOneToOne(command.entityName(), command.entityId(), final CommandProcessingResult commandProcessingResult = this.writePlatformService.updateDatatableEntryOneToOne(command.entityName(), command.entityId(),
command); command);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
.withEntityId(command.entityId()) // .withEntityId(command.entityId()) //
.with(changes) // .withOfficeId(commandProcessingResult.getOfficeId()) //
.build(); .withGroupId(commandProcessingResult.getGroupId()) //
.withClientId(commandProcessingResult.getClientId()) //
.withSavingsId(commandProcessingResult.getSavingsId()) //
.withLoanId(commandProcessingResult.getLoanId()) //
.with(commandProcessingResult.getChanges()) //
.build();
} }
} }
@@ -6,9 +6,9 @@
package org.mifosplatform.infrastructure.dataqueries.service; package org.mifosplatform.infrastructure.dataqueries.service;
import java.util.List; import java.util.List;
import java.util.Map;
import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.dataqueries.data.DatatableData; import org.mifosplatform.infrastructure.dataqueries.data.DatatableData;
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@@ -25,14 +25,14 @@ public interface ReadWriteNonCoreDataService {
GenericResultsetData retrieveDataTableGenericResultSet(String datatable, Long appTableId, String order, Long id); GenericResultsetData retrieveDataTableGenericResultSet(String datatable, Long appTableId, String order, Long id);
void createNewDatatableEntry(String datatable, Long appTableId, JsonCommand command); CommandProcessingResult createNewDatatableEntry(String datatable, Long appTableId, JsonCommand command);
Map<String, Object> updateDatatableEntryOneToOne(String datatable, Long appTableId, JsonCommand command); CommandProcessingResult updateDatatableEntryOneToOne(String datatable, Long appTableId, JsonCommand command);
Map<String, Object> updateDatatableEntryOneToMany(String datatable, Long appTableId, Long datatableId, JsonCommand command); CommandProcessingResult updateDatatableEntryOneToMany(String datatable, Long appTableId, Long datatableId, JsonCommand command);
void deleteDatatableEntries(String datatable, Long appTableId); CommandProcessingResult deleteDatatableEntries(String datatable, Long appTableId);
void deleteDatatableEntry(String datatable, Long appTableId, Long datatableId); CommandProcessingResult deleteDatatableEntry(String datatable, Long appTableId, Long datatableId);
} }
@@ -21,6 +21,8 @@ import org.hibernate.exception.ConstraintViolationException;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
@@ -108,7 +110,6 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
@Override @Override
public void registerDatatable(final String dataTableName, final String applicationTableName) { public void registerDatatable(final String dataTableName, final String applicationTableName) {
// FIXME - KW - hardcoded supported app tables are m_loan or m_client?
validateAppTable(applicationTableName); validateAppTable(applicationTableName);
final String registerDatatableSql = "insert into x_registered_table (registered_table_name, application_table_name) values ('" final String registerDatatableSql = "insert into x_registered_table (registered_table_name, application_table_name) values ('"
@@ -197,10 +198,11 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
@Transactional @Transactional
@Override @Override
public void createNewDatatableEntry(final String dataTableName, final Long appTableId, final JsonCommand command) { public CommandProcessingResult createNewDatatableEntry(final String dataTableName, final Long appTableId, final JsonCommand command) {
try { try {
final String appTable = getWithinScopeApplicationTableName(dataTableName, appTableId); final String appTable = queryForApplicationTableName(dataTableName);
CommandProcessingResult commandProcessingResult = checkMainResourceExistsWithinScope(appTable, appTableId);
final List<ResultsetColumnHeaderData> columnHeaders = this.genericDataService.fillResultsetColumnHeaders(dataTableName); final List<ResultsetColumnHeaderData> columnHeaders = this.genericDataService.fillResultsetColumnHeaders(dataTableName);
@@ -210,6 +212,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
final String sql = getAddSql(columnHeaders, dataTableName, getFKField(appTable), appTableId, dataParams); final String sql = getAddSql(columnHeaders, dataTableName, getFKField(appTable), appTableId, dataParams);
this.jdbcTemplate.update(sql); this.jdbcTemplate.update(sql);
return commandProcessingResult; //
} catch (ConstraintViolationException dve) { } catch (ConstraintViolationException dve) {
// NOTE: jdbctemplate throws a // NOTE: jdbctemplate throws a
// org.hibernate.exception.ConstraintViolationException even though // org.hibernate.exception.ConstraintViolationException even though
@@ -236,103 +241,112 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
@Transactional @Transactional
@Override @Override
public Map<String, Object> updateDatatableEntryOneToOne(final String datatable, final Long appTableId, final JsonCommand command) { public CommandProcessingResult updateDatatableEntryOneToOne(final String dataTableName, final Long appTableId, final JsonCommand command) {
final GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, null); return updateDatatableEntry(dataTableName, appTableId, null, command);
}
if (grs.hasNoEntries()) { throw new DatatableNotFoundException(datatable, appTableId); } @Transactional
@Override
public CommandProcessingResult updateDatatableEntryOneToMany(final String dataTableName, final Long appTableId, final Long datatableId,
final JsonCommand command) {
return updateDatatableEntry(dataTableName, appTableId, datatableId, command);
}
private CommandProcessingResult updateDatatableEntry(final String dataTableName, final Long appTableId, final Long datatableId,
final JsonCommand command) {
final String appTable = queryForApplicationTableName(dataTableName);
CommandProcessingResult commandProcessingResult = checkMainResourceExistsWithinScope(appTable, appTableId);
final GenericResultsetData grs = retrieveDataTableGenericResultSetForUpdate(appTable, dataTableName, appTableId, datatableId);
if (grs.hasNoEntries()) { throw new DatatableNotFoundException(dataTableName, appTableId); }
if (grs.hasMoreThanOneEntry()) { throw new PlatformDataIntegrityException("error.msg.attempting.multiple.update", if (grs.hasMoreThanOneEntry()) { throw new PlatformDataIntegrityException("error.msg.attempting.multiple.update",
"Application table: " + datatable + " Foreign key id: " + appTableId); } "Application table: " + dataTableName + " Foreign key id: " + appTableId); }
final String fkName = getFKField(queryForApplicationTableName(datatable));
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json()); Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
final Map<String, Object> changes = getAffectedAndChangedColumns(grs, dataParams, fkName); String pkName = "id"; //1:M datatable
if (datatableId == null) { pkName = getFKField(appTable);} //1:1 datatable
final Map<String, Object> changes = getAffectedAndChangedColumns(grs, dataParams, pkName);
if (!changes.isEmpty()) { if (!changes.isEmpty()) {
final String updateOneToOneDatatableSql = getUpdateSql(datatable, fkName, appTableId, changes); Long pkValue = appTableId;
if (datatableId != null) { pkValue = datatableId;}
if (StringUtils.isNotBlank(updateOneToOneDatatableSql)) { final String sql = getUpdateSql(dataTableName, pkName, pkValue, changes);
this.jdbcTemplate.update(updateOneToOneDatatableSql); logger.info("Update sql: " + sql);
if (StringUtils.isNotBlank(sql)) {
this.jdbcTemplate.update(sql);
changes.put("locale", dataParams.get("locale")); changes.put("locale", dataParams.get("locale"));
changes.put("dateFormat", "yyyy-MM-dd"); changes.put("dateFormat", "yyyy-MM-dd");
} } else {
logger.info("No Changes");
}
} }
return changes; return new CommandProcessingResultBuilder() //
.withOfficeId(commandProcessingResult.getOfficeId()) //
.withGroupId(commandProcessingResult.getGroupId()) //
.withClientId(commandProcessingResult.getClientId()) //
.withSavingsId(commandProcessingResult.getSavingsId()) //
.withLoanId(commandProcessingResult.getLoanId()) //
.with(changes) //
.build();
} }
@Transactional @Transactional
@Override @Override
public Map<String, Object> updateDatatableEntryOneToMany(final String datatable, final Long appTableId, final Long datatableId, public CommandProcessingResult deleteDatatableEntries(final String dataTableName, final Long appTableId) {
final JsonCommand command) {
final GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, datatableId); final String appTable = queryForApplicationTableName(dataTableName);
CommandProcessingResult commandProcessingResult = checkMainResourceExistsWithinScope(appTable, appTableId);
if (grs.getData().size() == 0) throw new DatatableNotFoundException(datatable, appTableId);
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType(); final String deleteOneToOneEntrySql = getDeleteEntriesSql(dataTableName, getFKField(appTable), appTableId);
final Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
final Map<String, Object> changes = getAffectedAndChangedColumns(grs, dataParams, "id");
if (changes.size() == 0) return changes;
final String sql = getUpdateSql(datatable, "id", datatableId, changes);
if (StringUtils.isNotBlank(sql)) {
this.jdbcTemplate.update(sql);
changes.put("locale", dataParams.get("locale"));
changes.put("dateFormat", "yyyy-MM-dd");
} else {
logger.info("No Changes");
}
return changes;
}
@Transactional
@Override
public void deleteDatatableEntries(final String datatable, final Long appTableId) {
final String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
final String deleteOneToOneEntrySql = getDeleteEntriesSql(datatable, getFKField(appTable), appTableId);
int rowsDeleted = this.jdbcTemplate.update(deleteOneToOneEntrySql); int rowsDeleted = this.jdbcTemplate.update(deleteOneToOneEntrySql);
if (rowsDeleted < 1) { throw new DatatableNotFoundException(datatable, appTableId); } if (rowsDeleted < 1) { throw new DatatableNotFoundException(dataTableName, appTableId); }
return commandProcessingResult;
} }
@Transactional @Transactional
@Override @Override
public void deleteDatatableEntry(final String datatable, final Long appTableId, final Long datatableId) { public CommandProcessingResult deleteDatatableEntry(final String dataTableName, final Long appTableId, final Long datatableId) {
getWithinScopeApplicationTableName(datatable, appTableId); final String appTable = queryForApplicationTableName(dataTableName);
CommandProcessingResult commandProcessingResult = checkMainResourceExistsWithinScope(appTable, appTableId);
final String sql = getDeleteEntrySql(datatable, datatableId); final String sql = getDeleteEntrySql(dataTableName, datatableId);
this.jdbcTemplate.update(sql); this.jdbcTemplate.update(sql);
return commandProcessingResult;
} }
@Override @Override
public GenericResultsetData retrieveDataTableGenericResultSet(final String datatable, final Long appTableId, final String order, public GenericResultsetData retrieveDataTableGenericResultSet(final String dataTableName, final Long appTableId, final String order,
final Long id) { final Long id) {
final String appTable = getWithinScopeApplicationTableName(datatable, appTableId); final String appTable = queryForApplicationTableName(dataTableName);
checkMainResourceExistsWithinScope(appTable, appTableId);
final List<ResultsetColumnHeaderData> columnHeaders = this.genericDataService.fillResultsetColumnHeaders(datatable); final List<ResultsetColumnHeaderData> columnHeaders = this.genericDataService.fillResultsetColumnHeaders(dataTableName);
String sql = ""; String sql = "";
// id only used for reading a specific entry in a one to many datatable // id only used for reading a specific entry in a one to many datatable
// (when updating) // (when updating)
if (id == null) { if (id == null) {
sql = sql + "select * from `" + datatable + "` where " + getFKField(appTable) + " = " + appTableId; sql = sql + "select * from `" + dataTableName + "` where " + getFKField(appTable) + " = " + appTableId;
} else { } else {
sql = sql + "select * from `" + datatable + "` where id = " + id; sql = sql + "select * from `" + dataTableName + "` where id = " + id;
} }
if (order != null) { if (order != null) {
@@ -344,19 +358,59 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return new GenericResultsetData(columnHeaders, result); return new GenericResultsetData(columnHeaders, result);
} }
private void checkMainResourceExistsWithinScope(final String appTable, final Long appTableId) {
final String unscopedSql = "select t.id from `" + appTable + "` t ${dataScopeCriteria} where t.id = " + appTableId; private GenericResultsetData retrieveDataTableGenericResultSetForUpdate(final String appTable, String dataTableName, final Long appTableId,
final Long id) {
final String sql = dataScopedSQL(unscopedSql, appTable); final List<ResultsetColumnHeaderData> columnHeaders = this.genericDataService.fillResultsetColumnHeaders(dataTableName);
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(sql); String sql = "";
if (!rs.next()) { throw new DatatableNotFoundException(appTable, appTableId); } // id only used for reading a specific entry in a one to many datatable
// (when updating)
if (id == null) {
sql = sql + "select * from `" + dataTableName + "` where " + getFKField(appTable) + " = " + appTableId;
} else {
sql = sql + "select * from `" + dataTableName + "` where id = " + id;
}
final List<ResultsetRowData> result = fillDatatableResultSetDataRows(sql);
return new GenericResultsetData(columnHeaders, result);
} }
private String dataScopedSQL(final String unscopedSQL, final String appTable) { private CommandProcessingResult checkMainResourceExistsWithinScope(final String appTable, final Long appTableId) {
String dataScopeCriteria = null;
final String sql = dataScopedSQL(appTable, appTableId);
logger.info("data scoped sql: " + sql);
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(sql);
if (!rs.next()) { throw new DatatableNotFoundException(appTable, appTableId); }
Long officeId = getLongSqlRowSet(rs, "officeId");
Long groupId = getLongSqlRowSet(rs, "groupId");
Long clientId = getLongSqlRowSet(rs, "clientId");
Long savingsId = getLongSqlRowSet(rs, "savingsId");
Long LoanId = getLongSqlRowSet(rs, "loanId");
return new CommandProcessingResultBuilder() //
.withOfficeId(officeId) //
.withGroupId(groupId) //
.withClientId(clientId) //
.withSavingsId(savingsId) //
.withLoanId(LoanId) //
.build();
}
private Long getLongSqlRowSet(SqlRowSet rs, String column) {
Long val = rs.getLong(column);
if (val == 0) val = null;
return val;
}
private String dataScopedSQL(final String appTable, final Long appTableId) {
/* /*
* unfortunately have to, one way or another, be able to restrict data * unfortunately have to, one way or another, be able to restrict data
* to the users office hierarchy. Here it's hardcoded for client and * to the users office hierarchy. Here it's hardcoded for client and
@@ -366,31 +420,44 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
*/ */
AppUser currentUser = context.authenticatedUser(); AppUser currentUser = context.authenticatedUser();
String scopedSQL = null;
if (appTable.equalsIgnoreCase("m_loan")) { if (appTable.equalsIgnoreCase("m_loan")) {
dataScopeCriteria = " join m_client c on c.id = t.client_id " + " join m_office o on o.id = c.office_id and o.hierarchy like '" scopedSQL = "select o.id as officeId, null as groupId, c.id as clientId, null as savingsId, l.id as loanId from m_loan l " +
+ currentUser.getOffice().getHierarchy() + "%'"; " join m_client c on c.id = l.client_id " +
" join m_office o on o.id = c.office_id and o.hierarchy like '" +
currentUser.getOffice().getHierarchy() + "%'" +
" where l.id = " + appTableId;
} }
if (appTable.equalsIgnoreCase("m_savings_account")) { if (appTable.equalsIgnoreCase("m_savings_account")) {
dataScopeCriteria = " join m_client c on c.id = t.client_id " + " join m_office o on o.id = c.office_id and o.hierarchy like '" scopedSQL = "select o.id as officeId, null as groupId, c.id as clientId, s.id as savingsId, null as loanId from m_savings_account s " +
+ currentUser.getOffice().getHierarchy() + "%'"; " join m_client c on c.id = s.client_id " +
" join m_office o on o.id = c.office_id and o.hierarchy like '" +
currentUser.getOffice().getHierarchy() + "%'" +
" where s.id = " + appTableId;
} }
if (appTable.equalsIgnoreCase("m_client")) { if (appTable.equalsIgnoreCase("m_client")) {
dataScopeCriteria = " join m_office o on o.id = t.office_id and o.hierarchy like '" + currentUser.getOffice().getHierarchy() scopedSQL = "select o.id as officeId, null as groupId, c.id as clientId, null as savingsId, null as loanId from m_client c " +
+ "%'"; " join m_office o on o.id = c.office_id and o.hierarchy like '" +
currentUser.getOffice().getHierarchy() + "%'" +
" where c.id = " + appTableId;
} }
if (appTable.equalsIgnoreCase("m_group")) { if (appTable.equalsIgnoreCase("m_group")) {
dataScopeCriteria = " join m_office o on o.id = t.office_id and o.hierarchy like '" scopedSQL = "select o.id as officeId, g.id as groupId, null as clientId, null as savingsId, null as loanId from m_group g " +
+ currentUser.getOffice().getHierarchy() + "%'"; " join m_office o on o.id = g.office_id and o.hierarchy like '" +
currentUser.getOffice().getHierarchy() + "%'" +
" where g.id = " + appTableId;
} }
if (appTable.equalsIgnoreCase("m_office")) { if (appTable.equalsIgnoreCase("m_office")) {
dataScopeCriteria = " join m_office o on o.id = t.id and o.hierarchy like '" scopedSQL = "select o.id as officeId, null as groupId, null as clientId, null as savingsId, null as loanId from m_office o " +
+ currentUser.getOffice().getHierarchy() + "%'"; " where o.hierarchy like '" +
currentUser.getOffice().getHierarchy() + "%'" +
" and o.id = " + appTableId;
} }
if (dataScopeCriteria == null) { throw new PlatformDataIntegrityException("error.msg.invalid.dataScopeCriteria", if (scopedSQL == null) { throw new PlatformDataIntegrityException("error.msg.invalid.dataScopeCriteria",
"Application Table: " + appTable + " not catered for in data Scoping"); } "Application Table: " + appTable + " not catered for in data Scoping"); }
return genericDataService.replace(unscopedSQL, "${dataScopeCriteria}", dataScopeCriteria); return scopedSQL;
} }
@@ -428,14 +495,6 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return resultsetDataRows; return resultsetDataRows;
} }
private String getWithinScopeApplicationTableName(final String datatable, final Long appTableId) {
final String applicationTableName = queryForApplicationTableName(datatable);
checkMainResourceExistsWithinScope(applicationTableName, appTableId);
return applicationTableName;
}
private String queryForApplicationTableName(final String datatable) { private String queryForApplicationTableName(final String datatable) {
final String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'"; final String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'";