MIFOSX-97: breakout client notes subresource into its own class.

This commit is contained in:
Keith Woodlock
2012-12-05 14:28:31 +00:00
parent b680e50942
commit add6708ab0
19 changed files with 624 additions and 346 deletions
@@ -182,4 +182,8 @@ public class CommandSource extends AbstractPersistable<Long> {
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");
}
}
@@ -0,0 +1,105 @@
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.commands.service.ChangeDetectionService;
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 ChangeDetectionService changeDetectionService;
private final ClientWritePlatformService clientWritePlatformService;
private final ClientNoteCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
@Autowired
public ClientNoteCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
final ClientNoteCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final ClientWritePlatformService clientWritePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
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 {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final ClientNoteCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(
commandSource.resourceId(), jsonOfChangesOnly);
this.clientWritePlatformService.updateNote(changesOnly);
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;
}
}
@@ -26,11 +26,13 @@ public class CommandSourceHandlerDelegator {
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,
@@ -45,6 +47,7 @@ public class CommandSourceHandlerDelegator {
this.context = context;
this.clientCommandHandler = clientCommandHandler;
this.clientIdentifierCommandHandler = clientIdentifierCommandHandler;
this.clientNoteCommandHandler = clientNoteCommandHandler;
this.roleCommandHandler = roleCommandHandler;
this.permissionCommandHandler = permissionCommandHandler;
this.userCommandHandler = userCommandHandler;
@@ -66,6 +69,8 @@ public class CommandSourceHandlerDelegator {
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()) {
@@ -102,6 +107,8 @@ public class CommandSourceHandlerDelegator {
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()) {
@@ -13,7 +13,6 @@ import org.mifosplatform.infrastructure.security.data.AuthenticatedUserData;
import org.mifosplatform.organisation.staff.data.BulkTransferLoanOfficerData;
import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData;
import org.mifosplatform.portfolio.client.data.NoteData;
import org.mifosplatform.portfolio.group.data.GroupAccountSummaryCollectionData;
import org.mifosplatform.portfolio.group.data.GroupData;
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
@@ -79,10 +78,6 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi
private static final Set<String> GROUP_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "officeId", "name", "externalId",
"clientMembers", "allowedClients", "allowedOffices"));
private static final Set<String> NOTE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "clientId", "loanId",
"loanTransactionId", "noteType", "note", "createdById", "createdByUsername", "createdOn", "updatedById", "updatedByUsername",
"updatedOn"));
private static final Set<String> LOAN_SCHEDULE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("periods",
"cumulativePrincipalDisbursed"));
@@ -213,20 +208,6 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi
return helper.serializedJsonFrom(gsonDeserializer, group);
}
@Override
public String serializeNoteDataToJson(boolean prettyPrint, Set<String> responseParameters, Collection<NoteData> notes) {
final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(NOTE_DATA_PARAMETERS,
prettyPrint, responseParameters);
return helper.serializedJsonFrom(gsonDeserializer, notes.toArray(new NoteData[notes.size()]));
}
@Override
public String serializeNoteDataToJson(final boolean prettyPrint, final Set<String> responseParameters, final NoteData note) {
final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(NOTE_DATA_PARAMETERS,
prettyPrint, responseParameters);
return helper.serializedJsonFrom(gsonDeserializer, note);
}
@Override
public String serializeLoanScheduleDataToJson(final boolean prettyPrint, final Set<String> responseParameters,
final LoanScheduleData loanSchedule) {
@@ -10,7 +10,6 @@ import org.mifosplatform.infrastructure.security.data.AuthenticatedUserData;
import org.mifosplatform.organisation.staff.data.BulkTransferLoanOfficerData;
import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData;
import org.mifosplatform.portfolio.client.data.NoteData;
import org.mifosplatform.portfolio.group.data.GroupAccountSummaryCollectionData;
import org.mifosplatform.portfolio.group.data.GroupData;
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
@@ -53,10 +52,6 @@ public interface PortfolioApiJsonSerializerService {
String serializeGroupDataToJson(boolean prettyPrint, Set<String> responseParameters, GroupData group);
String serializeNoteDataToJson(boolean prettyPrint, Set<String> responseParameters, Collection<NoteData> notes);
String serializeNoteDataToJson(boolean prettyPrint, Set<String> responseParameters, NoteData note);
String serializeLoanScheduleDataToJson(boolean prettyPrint, Set<String> responseParameters, LoanScheduleData loanSchedule);
String serializeLoanTransactionDataToJson(boolean prettyPrint, Set<String> responseParameters, LoanTransactionData newTransactionData);
@@ -17,8 +17,6 @@ import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSourc
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeader;
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetDataRow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -28,8 +26,6 @@ import com.sun.rowset.CachedRowSetImpl;
@Service
public class GenericDataServiceImpl implements GenericDataService {
private final static Logger logger = LoggerFactory.getLogger(GenericDataServiceImpl.class);
private final DataSource dataSource;
@Autowired
@@ -39,11 +35,11 @@ public class GenericDataServiceImpl implements GenericDataService {
}
@Override
public CachedRowSet getCachedResultSet(String sql, String sqlErrorMsg) {
public CachedRowSet getCachedResultSet(final String sql, final String sqlErrorMsg) {
// TODO - Need to reimplement this away from Sun library - could be
// mixture of Lists and jdbcTemplate.query
long startTime = System.currentTimeMillis();
// long startTime = System.currentTimeMillis();
Connection db_connection = null;
Statement db_statement = null;
CachedRowSet crs = null;
@@ -63,15 +59,15 @@ public class GenericDataServiceImpl implements GenericDataService {
}
long elapsed = System.currentTimeMillis() - startTime;
//logger.info("Elapsed Time: " + elapsed + " SQL: " + sql);
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("Elapsed Time: " + elapsed + " SQL: " + sql);
return crs;
}
@Override
public void updateSQL(String sql, String sqlErrorMsg) {
public void updateSQL(final String sql, final String sqlErrorMsg) {
long startTime = System.currentTimeMillis();
// long startTime = System.currentTimeMillis();
Connection db_connection = null;
Statement db_statement = null;
try {
@@ -84,8 +80,9 @@ public class GenericDataServiceImpl implements GenericDataService {
dbClose(db_statement, db_connection);
}
long elapsed = System.currentTimeMillis() - startTime;
//logger.info("Elapsed Time FOR UPDATE: " + elapsed + " SQL: " + sql);
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("Elapsed Time FOR UPDATE: " + elapsed + " SQL: " +
// sql);
}
@Override
@@ -129,7 +126,7 @@ public class GenericDataServiceImpl implements GenericDataService {
}
@Override
public String replace(String str, String pattern, String replace) {
public String replace(final String str, final String pattern, final String replace) {
// JPW - this replace may / may not be any better or quicker than the
// apache stringutils equivalent. It works, but if someone shows the
// apache one to be about the same then this can be removed.
@@ -147,7 +144,7 @@ public class GenericDataServiceImpl implements GenericDataService {
}
@Override
public String wrapSQL(String sql) {
public String wrapSQL(final String sql) {
// wrap sql to prevent JDBC sql errors, prevent malicious sql and a
// CachedRowSetImpl bug
@@ -158,21 +155,21 @@ public class GenericDataServiceImpl implements GenericDataService {
}
@Override
public String generateJsonFromGenericResultsetData(GenericResultsetData grs) {
public String generateJsonFromGenericResultsetData(final GenericResultsetData grs) {
StringBuffer writer = new StringBuffer();
writer.append("[");
List<ResultsetColumnHeader> columnHeaders = grs.getColumnHeaders();
//logger.info("NO. of Columns: " + columnHeaders.size());
// logger.info("NO. of Columns: " + columnHeaders.size());
List<ResultsetDataRow> data = grs.getData();
List<String> row;
Integer rSize;
String currColType;
String currVal;
//logger.info("NO. of Rows: " + data.size());
// logger.info("NO. of Rows: " + data.size());
for (int i = 0; i < data.size(); i++) {
writer.append("\n{");
@@ -212,7 +209,7 @@ public class GenericDataServiceImpl implements GenericDataService {
}
private void dbClose(Statement db_statement, Connection db_connection) {
//logger.debug("dbClose");
// logger.debug("dbClose");
try {
if (db_statement != null) {
db_statement.close();
@@ -45,9 +45,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
private GenericDataService genericDataService;
@Override
public List<DatatableData> retrieveDatatableNames(String appTable) {
public List<DatatableData> retrieveDatatableNames(final String appTable) {
long startTime = System.currentTimeMillis();
// long startTime = System.currentTimeMillis();
String andClause;
if (appTable == null) {
@@ -76,16 +76,17 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg);
}
long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING retrieveDatatableNames: Elapsed Time: " + elapsed);
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("FINISHING retrieveDatatableNames: Elapsed Time: " +
// elapsed);
return datatables;
}
@Override
public void registerDatatable(String datatable, String appTable) {
public void registerDatatable(final String datatable, final String appTable) {
long startTime = System.currentTimeMillis();
// long startTime = System.currentTimeMillis();
validateAppTable(appTable);
@@ -115,14 +116,15 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
genericDataService.updateSQL(sql, "SQL: " + sql);
long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING registerDatatable: Elapsed Time: " + elapsed + " - datatable: " + datatable
// + " application table: " + appTable);
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("FINISHING registerDatatable: Elapsed Time: " +
// elapsed + " - datatable: " + datatable
// + " application table: " + appTable);
}
@Override
public void deregisterDatatable(String datatable) {
long startTime = System.currentTimeMillis();
public void deregisterDatatable(final String datatable) {
// long startTime = System.currentTimeMillis();
// TODO - put in batch command later
@@ -139,13 +141,14 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
sql = "delete from x_registered_table where registered_table_name = '" + datatable + "'";
genericDataService.updateSQL(sql, "SQL: " + sql);
long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING deregisterDatatable: Elapsed Time: " + elapsed + " - datatable: " + datatable);
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("FINISHING deregisterDatatable: Elapsed Time: " +
// elapsed + " - datatable: " + datatable);
}
@Override
public void newDatatableEntry(String datatable, Long appTableId, Map<String, String> queryParams) {
long startTime = System.currentTimeMillis();
public void newDatatableEntry(final String datatable, final Long appTableId, final Map<String, String> queryParams) {
// long startTime = System.currentTimeMillis();
String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
@@ -155,15 +158,16 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
genericDataService.updateSQL(sql, "SQL: " + sql);
long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING newDatatableEntry: Elapsed Time: " + elapsed + " - datatable: " + datatable + " id: "
// + appTableId);
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("FINISHING newDatatableEntry: Elapsed Time: " +
// elapsed + " - datatable: " + datatable + " id: "
// + appTableId);
}
@Override
public void updateDatatableEntryOnetoOne(String datatable, Long appTableId, Map<String, String> queryParams) {
long startTime = System.currentTimeMillis();
public void updateDatatableEntryOnetoOne(final String datatable, final Long appTableId, final Map<String, String> queryParams) {
// long startTime = System.currentTimeMillis();
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, null);
@@ -176,20 +180,23 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
String fkName = getFKField(getApplicationTableName(datatable));
String sql = getUpdateSql(grs, datatable, fkName, appTableId, queryParams);
if (sql != null)
if (sql != null) {
genericDataService.updateSQL(sql, "SQL: " + sql);
else
} else {
logger.info("No Changes");
}
long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: " + elapsed + " - datatable: " + datatable + fkName
// + ": " + appTableId);
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: "
// + elapsed + " - datatable: " + datatable + fkName
// + ": " + appTableId);
}
@Override
public void updateDatatableEntryOnetoMany(String datatable, Long appTableId, Long datatableId, Map<String, String> queryParams) {
long startTime = System.currentTimeMillis();
public void updateDatatableEntryOnetoMany(final String datatable, final Long appTableId, final Long datatableId,
final Map<String, String> queryParams) {
// long startTime = System.currentTimeMillis();
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, datatableId);
@@ -197,19 +204,21 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
String sql = getUpdateSql(grs, datatable, "id", datatableId, queryParams);
if (sql != null)
if (sql != null) {
genericDataService.updateSQL(sql, "SQL: " + sql);
else
} else {
logger.info("No Changes");
}
long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: " + elapsed + " - datatable: " + datatable + " id: "
// + datatableId);
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: "
// + elapsed + " - datatable: " + datatable + " id: "
// + datatableId);
}
@Override
public void deleteDatatableEntries(String datatable, Long appTableId) {
long startTime = System.currentTimeMillis();
public void deleteDatatableEntries(final String datatable, final Long appTableId) {
// long startTime = System.currentTimeMillis();
String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
@@ -217,15 +226,16 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
genericDataService.updateSQL(sql, "SQL: " + sql);
long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING deleteDatatableEntries: Elapsed Time: " + elapsed + " - datatable: " + datatable
// + " App Table Id: " + appTableId);
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("FINISHING deleteDatatableEntries: Elapsed Time: " +
// elapsed + " - datatable: " + datatable
// + " App Table Id: " + appTableId);
}
@Override
public void deleteDatatableEntry(String datatable, Long appTableId, Long datatableId) {
long startTime = System.currentTimeMillis();
public void deleteDatatableEntry(final String datatable, final Long appTableId, final Long datatableId) {
// long startTime = System.currentTimeMillis();
getWithinScopeApplicationTableName(datatable, appTableId);
@@ -233,16 +243,19 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
genericDataService.updateSQL(sql, "SQL: " + sql);
long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING deleteDatatableEntry: Elapsed Time: " + elapsed + " - datatable: " + datatable
// + " App Table Id: " + appTableId + " Data Table Id: " + datatableId);
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("FINISHING deleteDatatableEntry: Elapsed Time: " +
// elapsed + " - datatable: " + datatable
// + " App Table Id: " + appTableId + " Data Table Id: " +
// datatableId);
}
@Override
public GenericResultsetData retrieveDataTableGenericResultSet(String datatable, Long appTableId, String order, Long id) {
public GenericResultsetData retrieveDataTableGenericResultSet(final String datatable, final Long appTableId, final String order,
final Long id) {
long startTime = System.currentTimeMillis();
// long startTime = System.currentTimeMillis();
String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
@@ -262,14 +275,15 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
List<ResultsetDataRow> result = fillDatatableResultSetDataRows(sql);
long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING DATATABLE: " + datatable + " Elapsed Time: " + elapsed + " SQL: " + sql);
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("FINISHING DATATABLE: " + datatable +
// " Elapsed Time: " + elapsed + " SQL: " + sql);
return new GenericResultsetData(columnHeaders, result);
}
private void checkMainResourceExistsWithinScope(String appTable, Long appTableId) {
private void checkMainResourceExistsWithinScope(final String appTable, final Long appTableId) {
String unscopedSql = "select t.id from `" + appTable + "` t ${dataScopeCriteria} where t.id = " + appTableId;
@@ -280,7 +294,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
if (rs.size() == 0) throw new DataTableNotFoundException(appTable, appTableId);
}
private String dataScopedSQL(String unscopedSQL, String appTable) {
private String dataScopedSQL(final String unscopedSQL, final String appTable) {
String dataScopeCriteria = null;
/*
* unfortunately have to, one way or another, be able to restrict data
@@ -307,7 +321,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
private void validateAppTable(String appTable) {
private void validateAppTable(final String appTable) {
if (appTable.equalsIgnoreCase("m_client")) return;
if (appTable.equalsIgnoreCase("m_loan")) return;
@@ -348,7 +362,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
}
private String getWithinScopeApplicationTableName(String datatable, Long appTableId) {
private String getWithinScopeApplicationTableName(final String datatable, final Long appTableId) {
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'";
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql);
@@ -367,7 +381,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
}
private String getApplicationTableName(String datatable) {
private String getApplicationTableName(final String datatable) {
// TODO - only used for update... can probably remove this after as its
// a reread
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'";
@@ -384,12 +398,12 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
}
private String getFKField(String applicationTableName) {
private String getFKField(final String applicationTableName) {
return applicationTableName.substring(2) + "_id";
}
private CachedRowSet getDatatableMetaData(String datatable) {
private CachedRowSet getDatatableMetaData(final String datatable) {
String sql = "select COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMN_KEY"
+ " from INFORMATION_SCHEMA.COLUMNS " + " where TABLE_SCHEMA = schema() and TABLE_NAME = '" + datatable
@@ -402,7 +416,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
throw new DataTableNotFoundException(datatable);
}
private List<ResultsetColumnHeader> getDatatableResultsetColumnHeaders(String datatable) {
private List<ResultsetColumnHeader> getDatatableResultsetColumnHeaders(final String datatable) {
CachedRowSet columnDefinitions = getDatatableMetaData(datatable);
@@ -450,7 +464,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
private void addCodesValueIfNecessary(ResultsetColumnHeader rsch, String code_suffix) {
private void addCodesValueIfNecessary(final ResultsetColumnHeader rsch, final String code_suffix) {
int codePosition = rsch.getColumnName().indexOf(code_suffix);
if (codePosition > 0) {
String codeName = rsch.getColumnName().substring(0, codePosition);
@@ -471,10 +485,10 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
private String getAddSql(List<ResultsetColumnHeader> columnHeaders, String datatable, String fkName, Long appTableId,
Map<String, String> queryParams) {
private String getAddSql(final List<ResultsetColumnHeader> columnHeaders, final String datatable, final String fkName,
final Long appTableId, final Map<String, String> queryParams) {
Map<String, String> affectedColumns = getAffectedColumns(columnHeaders, queryParams, fkName);
final Map<String, String> affectedColumns = getAffectedColumns(columnHeaders, queryParams, fkName);
String pValueWrite = "";
String addSql = "";
@@ -503,10 +517,10 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return addSql;
}
private String getUpdateSql(GenericResultsetData grs, String datatable, String keyFieldName, Long keyFieldValue,
Map<String, String> queryParams) {
private String getUpdateSql(final GenericResultsetData grs, final String datatable, final String keyFieldName,
final Long keyFieldValue, final Map<String, String> queryParams) {
Map<String, String> affectedAndChangedColumns = getAffectedAndChangedColumns(grs, queryParams, keyFieldName);
final Map<String, String> affectedAndChangedColumns = getAffectedAndChangedColumns(grs, queryParams, keyFieldName);
// just updating fields that have changed since pre-update read - though
// its possible these values are different from the page the user was
@@ -545,7 +559,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return sql;
}
private Map<String, String> getAffectedAndChangedColumns(GenericResultsetData grs, Map<String, String> queryParams, String fkName) {
private Map<String, String> getAffectedAndChangedColumns(final GenericResultsetData grs, final Map<String, String> queryParams,
final String fkName) {
Map<String, String> affectedColumns = getAffectedColumns(grs.getColumnHeaders(), queryParams, fkName);
Map<String, String> affectedAndChangedColumns = new HashMap<String, String>();
@@ -561,7 +576,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return affectedAndChangedColumns;
}
private boolean columnChanged(String key, String keyValue, GenericResultsetData grs) {
private boolean columnChanged(final String key, final String keyValue, final GenericResultsetData grs) {
List<String> columnValues = grs.getData().get(0).getRow();
@@ -583,8 +598,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
throw new PlatformDataIntegrityException("error.msg.invalid.columnName", "Parameter Column Name: " + key + " not found");
}
private Map<String, String> getAffectedColumns(List<ResultsetColumnHeader> columnHeaders, Map<String, String> queryParams,
String keyFieldName) {
private Map<String, String> getAffectedColumns(final List<ResultsetColumnHeader> columnHeaders, final Map<String, String> queryParams,
final String keyFieldName) {
String dateFormat = queryParams.get("dateFormat");
Locale clientApplicationLocale = null;
@@ -628,7 +643,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return affectedColumns;
}
private String validateColumn(ResultsetColumnHeader columnHeader, String pValue, String dateFormat, Locale clientApplicationLocale) {
private String validateColumn(final ResultsetColumnHeader columnHeader, final String pValue, final String dateFormat,
final Locale clientApplicationLocale) {
String paramValue = pValue;
@@ -693,19 +709,19 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return paramValue;
}
private String getDeleteEntriesSql(String datatable, String FKField, Long appTableId) {
private String getDeleteEntriesSql(final String datatable, final String FKField, final Long appTableId) {
return "delete from `" + datatable + "` where `" + FKField + "` = " + appTableId;
}
private String getDeleteEntrySql(String datatable, Long datatableId) {
private String getDeleteEntrySql(final String datatable, final Long datatableId) {
return "delete from `" + datatable + "` where `id` = " + datatableId;
}
private boolean notTheSame(String currValue, String pValue) {
private boolean notTheSame(final String currValue, final String pValue) {
if (StringUtils.isEmpty(currValue) && StringUtils.isEmpty(pValue)) return false;
if (StringUtils.isEmpty(currValue)) return true;
@@ -716,5 +732,4 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return true;
}
}
@@ -31,8 +31,6 @@ import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.organisation.staff.serialization.StaffCommandFromApiJsonDeserializer;
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -42,8 +40,6 @@ import org.springframework.stereotype.Component;
@Scope("singleton")
public class StaffApiResource {
private final static Logger logger = LoggerFactory.getLogger(StaffApiResource.class);
/**
* The set of parameters that are supported in response for {@link CodeData}
*/
@@ -155,7 +151,6 @@ public class StaffApiResource {
if (StringUtils.isNotBlank(extraCriteria)) {
extraCriteria = extraCriteria.substring(4);
}
//logger.debug("extraCriteria; " + extraCriteria);
return extraCriteria;
}
@@ -0,0 +1,124 @@
package org.mifosplatform.portfolio.client.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.data.NoteData;
import org.mifosplatform.portfolio.client.serialization.ClientNoteCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Path("/clients/{clientId}/notes")
@Component
@Scope("singleton")
public class ClientNotesApiResource {
private final Set<String> NOTE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "clientId", "loanId", "loanTransactionId",
"noteType", "note", "createdById", "createdByUsername", "createdOn", "updatedById", "updatedByUsername", "updatedOn"));
private final PlatformSecurityContext context;
private final ClientReadPlatformService clientReadPlatformService;
private final ClientNoteCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<NoteData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired
public ClientNotesApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService,
final ClientNoteCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<NoteData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context;
this.clientReadPlatformService = readPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllClientNotes(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission("CLIENTNOTE");
final Collection<NoteData> notes = this.clientReadPlatformService.retrieveAllClientNotes(clientId);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, notes, NOTE_DATA_PARAMETERS);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String addNewClientNote(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "CREATE_CLIENTNOTE");
context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENTNOTE", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJsonWithSubResource(apiRequestBodyAsJson, clientId);
final String resourceUrl = "clients/" + clientId + "/notes";
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", resourceUrl, null,
commandSerializedAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@GET
@Path("{noteId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId,
@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission("CLIENTNOTE");
final NoteData note = this.clientReadPlatformService.retrieveClientNote(clientId, noteId);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, note, NOTE_DATA_PARAMETERS);
}
@PUT
@Path("{noteId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String updateClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId,
final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "UPDATE_CLIENTNOTE");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENTNOTE", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJsonWithSubResource(noteId, apiRequestBodyAsJson, clientId);
final String resourceUrl = "clients/" + clientId + "/notes";
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", resourceUrl, noteId,
commandSerializedAsJson);
return this.toApiJsonSerializer.serialize(result);
}
}
@@ -39,16 +39,12 @@ import org.mifosplatform.infrastructure.core.service.FileUtils;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.data.OfficeLookup;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.mifosplatform.portfolio.client.command.NoteCommand;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData;
import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.client.data.NoteData;
import org.mifosplatform.portfolio.client.exception.ImageNotFoundException;
import org.mifosplatform.portfolio.client.serialization.ClientCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.mifosplatform.portfolio.client.service.ClientWritePlatformService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -63,8 +59,6 @@ import com.sun.jersey.multipart.FormDataParam;
@Scope("singleton")
public class ClientsApiResource {
private final static Logger logger = LoggerFactory.getLogger(ClientsApiResource.class);
private final Set<String> CLIENT_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "officeId", "officeName", "externalId",
"firstname", "lastname", "joinedDate", "displayName", "clientOrBusinessName", "allowedOffices", "imagePresent"));
@@ -85,7 +79,7 @@ public class ClientsApiResource {
final ClientWritePlatformService clientWritePlatformService, final OfficeReadPlatformService officeReadPlatformService,
final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioApiDataConversionService apiDataConversionService,
final PortfolioApiDataConversionService apiDataConversionService,
final PortfolioApiJsonSerializerService apiJsonSerializerService,
final PortfolioCommandsReadPlatformService commandsReadPlatformService,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
@@ -158,7 +152,7 @@ public class ClientsApiResource {
extraCriteria = extraCriteria.substring(4);
}
//logger.info("extraCriteria; " + extraCriteria);
// logger.info("extraCriteria; " + extraCriteria);
return extraCriteria;
}
@@ -260,8 +254,9 @@ public class ClientsApiResource {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "UPDATE_CLIENT");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENT", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(clientId, apiRequestBodyAsJson);
final String commandSerializedAsJson = this.fromApiJsonDeserializer
.serializedCommandJsonFromApiJson(clientId, apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "clients", clientId,
commandSerializedAsJson);
@@ -299,66 +294,6 @@ public class ClientsApiResource {
clientAccount);
}
@GET
@Path("{clientId}/notes")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllClientNotes(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission("CLIENTNOTE");
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
final Collection<NoteData> notes = this.clientReadPlatformService.retrieveAllClientNotes(clientId);
return this.apiJsonSerializerService.serializeNoteDataToJson(prettyPrint, responseParameters, notes);
}
@POST
@Path("{clientId}/notes")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String addNewClientNote(@PathParam("clientId") final Long clientId, final String jsonRequestBody) {
final NoteCommand command = this.apiDataConversionService.convertJsonToNoteCommand(null, clientId, jsonRequestBody);
final EntityIdentifier result = this.clientWritePlatformService.addClientNote(command);
return this.toApiJsonSerializer.serialize(result);
}
@GET
@Path("{clientId}/notes/{noteId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId,
@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission("CLIENTNOTE");
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
final NoteData note = this.clientReadPlatformService.retrieveClientNote(clientId, noteId);
return this.apiJsonSerializerService.serializeNoteDataToJson(prettyPrint, responseParameters, note);
}
@PUT
@Path("{clientId}/notes/{noteId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String updateClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId,
final String jsonRequestBody) {
final NoteCommand command = this.apiDataConversionService.convertJsonToNoteCommand(noteId, clientId, jsonRequestBody);
final EntityIdentifier result = this.clientWritePlatformService.updateNote(command);
return this.toApiJsonSerializer.serialize(result);
}
/**
* Upload images through multi-part form upload
*/
@@ -0,0 +1,41 @@
package org.mifosplatform.portfolio.client.command;
import java.util.Set;
/**
* Immutable command used for create or update of notes.
*/
public class ClientNoteCommand {
private final Long clientId;
private final String note;
private final transient Long id;
private final transient Set<String> parametersPassedInRequest;
private final transient boolean makerCheckerApproval;
public static ClientNoteCommand clientSubResource(final ClientNoteCommand command, final Long providedClientId) {
return new ClientNoteCommand(command.parametersPassedInRequest, command.makerCheckerApproval, command.id, providedClientId, command.note);
}
public ClientNoteCommand(final Set<String> parametersPassedInRequest, final boolean makerCheckerApproval, final Long id, Long clientId,
final String note) {
this.parametersPassedInRequest = parametersPassedInRequest;
this.makerCheckerApproval = makerCheckerApproval;
this.id = id;
this.clientId = clientId;
this.note = note;
}
public Long getId() {
return id;
}
public Long getClientId() {
return clientId;
}
public String getNote() {
return note;
}
}
@@ -16,49 +16,56 @@ import org.mifosplatform.useradministration.domain.AppUser;
@Table(name = "m_note")
public class Note extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne
@ManyToOne
@JoinColumn(name = "client_id", nullable = false)
private final Client client;
@SuppressWarnings("unused")
@ManyToOne
@JoinColumn(name = "loan_id", nullable = true)
private Loan loan;
@SuppressWarnings("unused")
@ManyToOne
@JoinColumn(name = "loan_transaction_id", nullable = true)
private LoanTransaction loanTransaction;
private final Client client;
@SuppressWarnings("unused")
@Column(name = "note", length=1000)
private String note;
@ManyToOne
@JoinColumn(name = "loan_id", nullable = true)
private Loan loan;
@SuppressWarnings("unused")
@Column(name = "note_type_enum")
private Integer noteTypeId;
@ManyToOne
@JoinColumn(name = "loan_transaction_id", nullable = true)
private LoanTransaction loanTransaction;
@SuppressWarnings("unused")
@ManyToOne
@JoinColumn(name = "deposit_account_id", nullable = true)
private DepositAccount depositAccount;
@Column(name = "note", length = 1000)
private String note;
@SuppressWarnings("unused")
@Column(name = "note_type_enum")
private Integer noteTypeId;
// FIXME - madhukar - disabled relationship to DespositAccount as missing patch on fields on deposit account table that break functionality.
// @SuppressWarnings("unused")
// @ManyToOne
// @JoinColumn(name = "deposit_account_id", nullable = true)
// private DepositAccount depositAccount;
public enum NoteType {
CLIENT(100, "noteType.client"), LOAN(200, "noteType.loan"), LOAN_TRANSACTION(300, "noteType.loan.transaction"), DEPOSIT(400, "noteType.deposit");
CLIENT(100, "noteType.client"), LOAN(200, "noteType.loan"), LOAN_TRANSACTION(300, "noteType.loan.transaction"), DEPOSIT(400,
"noteType.deposit");
private Integer value;
private String code;
NoteType(final Integer value, final String code) { this.value = value; this.code = code; }
NoteType(final Integer value, final String code) {
this.value = value;
this.code = code;
}
public Integer getValue() { return value; }
public Integer getValue() {
return value;
}
public String getCode() {
return code;
}
return code;
}
public static NoteType parse(Integer id) {
NoteType right = null; // Default
public static NoteType parse(Integer id) {
NoteType right = null; // Default
for (NoteType item : NoteType.values()) {
if (item.getValue().intValue() == id.intValue()) {
right = item;
@@ -70,38 +77,38 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
}
public static Note clientNote(Client client, String note) {
return new Note(client, note);
}
return new Note(client, note);
}
public static Note loanNote(Loan loan, String note) {
return new Note(loan, note);
}
public static Note loanTransactionNote(Loan loan, LoanTransaction loanTransaction, String note) {
return new Note(loan, loanTransaction, note);
}
public static Note loanNote(Loan loan, String note) {
return new Note(loan, note);
}
public static Note loanTransactionNote(Loan loan, LoanTransaction loanTransaction, String note) {
return new Note(loan, loanTransaction, note);
}
private Note(Client client, String note) {
this.client = client;
this.note = note;
this.noteTypeId = NoteType.CLIENT.getValue();
}
this.client = client;
this.note = note;
this.noteTypeId = NoteType.CLIENT.getValue();
}
private Note(Loan loan, String note) {
this.loan = loan;
this.client = loan.client();
this.note = note;
this.noteTypeId = NoteType.LOAN.getValue();
}
this.loan = loan;
this.client = loan.client();
this.note = note;
this.noteTypeId = NoteType.LOAN.getValue();
}
private Note(Loan loan, LoanTransaction loanTransaction, String note) {
this.loan = loan;
this.loanTransaction = loanTransaction;
this.client = loan.client();
this.note = note;
this.noteTypeId = NoteType.LOAN_TRANSACTION.getValue();
}
this.loan = loan;
this.loanTransaction = loanTransaction;
this.client = loan.client();
this.note = note;
this.noteTypeId = NoteType.LOAN_TRANSACTION.getValue();
}
protected Note() {
this.client = null;
this.loan = null;
@@ -110,22 +117,22 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
this.noteTypeId = null;
}
public Note(DepositAccount account, String note) {
this.depositAccount=account;
this.client = account.client();
this.note = note;
this.noteTypeId = NoteType.DEPOSIT.getValue();
}
public Note(DepositAccount account, String note) {
// this.depositAccount = account;
this.client = account.client();
this.note = note;
this.noteTypeId = NoteType.DEPOSIT.getValue();
}
public void update(final String note) {
this.note = note;
}
public void update(final String note) {
this.note = note;
}
public boolean isNotAgainstClientWithIdOf(Long clientId) {
return !this.client.identifiedBy(clientId);
}
public boolean isNotAgainstClientWithIdOf(Long clientId) {
return !this.client.identifiedBy(clientId);
}
public static Note depositNote(DepositAccount account, String noteText) {
return new Note(account,noteText);
}
public static Note depositNote(DepositAccount account, String noteText) {
return new Note(account, noteText);
}
}
@@ -6,6 +6,7 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
@@ -21,7 +22,7 @@ import com.google.gson.reflect.TypeToken;
* 's.
*/
@Component
public final class ClientIdentifierCommandFromApiJsonDeserializer implements FromApiJsonDeserializer<ClientIdentifierCommand> {
public final class ClientIdentifierCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<ClientIdentifierCommand> {
/**
* The parameters supported for this command.
@@ -30,44 +31,27 @@ public final class ClientIdentifierCommandFromApiJsonDeserializer implements Fro
"description"));
private final FromJsonHelper fromApiJsonHelper;
private final CommandSerializer commandSerializerService;
private final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final CommandSerializer commandSerializerService;
@Autowired
public ClientIdentifierCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper,
final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final CommandSerializer commandSerializerService) {
super(commandSerializerService);
this.fromApiJsonHelper = fromApiJsonHelper;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.commandSerializerService = commandSerializerService;
}
@Override
public ClientIdentifierCommand commandFromApiJson(final String json) {
return commandFromApiJson(null, json);
}
@Override
public ClientIdentifierCommand commandFromApiJson(final Long clientId, final String json) {
public ClientIdentifierCommand commandFromApiJson(final Long clientIdentifierId, final String json) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
return this.commandFromCommandJsonDeserializer.commandFromCommandJson(clientId, json);
}
@Override
public String serializedCommandJsonFromApiJson(final String json) {
final ClientIdentifierCommand command = commandFromApiJson(json);
return this.commandSerializerService.serializeCommandToJson(command);
}
@Override
public String serializedCommandJsonFromApiJson(final Long clientIdentifierId, final String json) {
final ClientIdentifierCommand command = commandFromApiJson(clientIdentifierId, json);
return this.commandSerializerService.serializeCommandToJson(command);
return this.commandFromCommandJsonDeserializer.commandFromCommandJson(clientIdentifierId, json);
}
public String serializedCommandJsonFromApiJsonWithSubResource(final String json, final Long clientId) {
@@ -0,0 +1,68 @@
package org.mifosplatform.portfolio.client.serialization;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.portfolio.client.command.ClientNoteCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
/**
* Implementation of {@link FromApiJsonDeserializer} for {@link ClientCommand}
* 's.
*/
@Component
public final class ClientNoteCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<ClientNoteCommand> {
/**
* The parameters supported for this command.
*/
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("clientId", "note"));
private final FromJsonHelper fromApiJsonHelper;
private final CommandSerializer commandSerializerService;
@Autowired
public ClientNoteCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper, final CommandSerializer commandSerializerService) {
super(commandSerializerService);
this.fromApiJsonHelper = fromApiJsonHelper;
this.commandSerializerService = commandSerializerService;
}
@Override
public ClientNoteCommand commandFromApiJson(final Long noteId, final String json) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final Set<String> parametersPassedInRequest = new HashSet<String>();
final JsonElement element = fromApiJsonHelper.parse(json);
final Long clientId = fromApiJsonHelper.extractLongNamed("clientId", element, parametersPassedInRequest);
final String note = fromApiJsonHelper.extractStringNamed("note", element, parametersPassedInRequest);
return new ClientNoteCommand(parametersPassedInRequest, false, noteId, clientId, note);
}
public String serializedCommandJsonFromApiJsonWithSubResource(final String json, final Long clientId) {
return serializedCommandJsonFromApiJsonWithSubResource(null, json, clientId);
}
public String serializedCommandJsonFromApiJsonWithSubResource(final Long noteId, final String json, final Long clientId) {
final ClientNoteCommand command = commandFromApiJson(noteId, json);
final ClientNoteCommand commandWithSubResource = ClientNoteCommand.clientSubResource(command, clientId);
return this.commandSerializerService.serializeCommandToJson(commandWithSubResource);
}
}
@@ -0,0 +1,38 @@
package org.mifosplatform.portfolio.client.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.AbstractFromCommandJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.portfolio.client.command.ClientNoteCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
@Component
public final class ClientNoteCommandFromCommandJsonDeserializer extends AbstractFromCommandJsonDeserializer<ClientNoteCommand> {
private final FromJsonHelper fromJsonHelper;
@Autowired
public ClientNoteCommandFromCommandJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromJsonHelper = fromApiJsonHelper;
}
@Override
public ClientNoteCommand commandFromCommandJson(final Long noteId, 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 clientId = fromJsonHelper.extractLongNamed("clientId", element, parametersPassedInRequest);
final String note = fromJsonHelper.extractStringNamed("note", element, parametersPassedInRequest);
return new ClientNoteCommand(parametersPassedInRequest, makerCheckerApproval, noteId, clientId, note);
}
}
@@ -6,7 +6,7 @@ import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand;
import org.mifosplatform.portfolio.client.command.NoteCommand;
import org.mifosplatform.portfolio.client.command.ClientNoteCommand;
import org.springframework.security.access.prepost.PreAuthorize;
public interface ClientWritePlatformService {
@@ -26,11 +26,9 @@ public interface ClientWritePlatformService {
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'DELETE_CLIENTIMAGE')")
EntityIdentifier deleteClientImage(Long clientId);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_CLIENTNOTE')")
EntityIdentifier addClientNote(NoteCommand command);
EntityIdentifier addClientNote(ClientNoteCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'UPDATE_CLIENTNOTE')")
EntityIdentifier updateNote(NoteCommand command);
EntityIdentifier updateNote(ClientNoteCommand command);
Long addClientIdentifier(ClientIdentifierCommand command);
@@ -22,7 +22,7 @@ import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.portfolio.client.command.ClientCommandValidator;
import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand;
import org.mifosplatform.portfolio.client.command.ClientIdentifierCommandValidator;
import org.mifosplatform.portfolio.client.command.NoteCommand;
import org.mifosplatform.portfolio.client.command.ClientNoteCommand;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientIdentifier;
import org.mifosplatform.portfolio.client.domain.ClientIdentifierRepository;
@@ -166,7 +166,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional
@Override
public EntityIdentifier addClientNote(final NoteCommand command) {
public EntityIdentifier addClientNote(final ClientNoteCommand command) {
context.authenticatedUser();
@@ -182,7 +182,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional
@Override
public EntityIdentifier updateNote(final NoteCommand command) {
public EntityIdentifier updateNote(final ClientNoteCommand command) {
context.authenticatedUser();
@@ -34,8 +34,6 @@ import org.mifosplatform.portfolio.group.data.GroupAccountSummaryCollectionData;
import org.mifosplatform.portfolio.group.data.GroupData;
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
import org.mifosplatform.portfolio.group.service.GroupWritePlatformService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -45,8 +43,6 @@ import org.springframework.stereotype.Component;
@Scope("singleton")
public class GroupsApiResource {
private final static Logger logger = LoggerFactory.getLogger(GroupsApiResource.class);
@Autowired
private GroupReadPlatformService groupReadPlatformService;
@@ -62,27 +58,23 @@ public class GroupsApiResource {
@Autowired
private OfficeReadPlatformService officeReadPlatformService;
@Autowired
private PortfolioApiJsonSerializerService apiJsonSerializerService;
@Autowired
private PortfolioApiJsonSerializerService apiJsonSerializerService;
@Autowired
private PlatformSecurityContext context;
private static final Set<String> typicalResponseParameters = new HashSet<String>(
Arrays.asList("id", "officeId", "name", "externalId", "clientMembers")
);
private static final Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "officeId", "name", "externalId",
"clientMembers"));
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllGroups(@Context final UriInfo uriInfo,
@QueryParam("sqlSearch") final String sqlSearch,
@QueryParam("officeId") final Long officeId,
@QueryParam("externalId") final String externalId,
@QueryParam("name") final String name,
@QueryParam("underHierarchy") final String hierarchy){
context.authenticatedUser().validateHasReadPermission("GROUP");
public String retrieveAllGroups(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch,
@QueryParam("officeId") final Long officeId, @QueryParam("externalId") final String externalId,
@QueryParam("name") final String name, @QueryParam("underHierarchy") final String hierarchy) {
context.authenticatedUser().validateHasReadPermission("GROUP");
final String extraCriteria = getGroupExtraCriteria(sqlSearch, officeId, externalId, name, hierarchy);
@@ -102,14 +94,12 @@ public class GroupsApiResource {
@Path("{groupId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveGroupData(@Context final UriInfo uriInfo,
@PathParam("groupId") final Long groupId,
@QueryParam("officeId") final Long officeId) {
public String retrieveGroupData(@Context final UriInfo uriInfo, @PathParam("groupId") final Long groupId,
@QueryParam("officeId") final Long officeId) {
context.authenticatedUser().validateHasReadPermission("GROUP");
context.authenticatedUser().validateHasReadPermission("GROUP");
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo
.getQueryParameters());
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
@@ -124,34 +114,33 @@ public class GroupsApiResource {
group = new GroupData(group, clientMembers, availableClients, allowedOffices);
boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
if (template) {
responseParameters.add("allowedClients");
responseParameters.add("allowedOffices");
if (template) {
responseParameters.add("allowedClients");
responseParameters.add("allowedOffices");
if (officeId != null){
if (officeId != null) {
availableClients = this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(officeId);
} else {
availableClients = this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(group.getOfficeId());
}
availableClients.removeAll(group.clientMembers());
availableClients.removeAll(group.clientMembers());
allowedOffices = officeReadPlatformService.retrieveAllOfficesForLookup();
allowedOffices = officeReadPlatformService.retrieveAllOfficesForLookup();
group = new GroupData(group, group.clientMembers(), availableClients, allowedOffices);
}
group = new GroupData(group, group.clientMembers(), availableClients, allowedOffices);
}
return this.apiJsonSerializerService.serializeGroupDataToJson(prettyPrint, responseParameters, group);
}
@GET
@Path("template")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String newGroupDetails(@Context final UriInfo uriInfo,
@QueryParam("officeId") final Long officeId) {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String newGroupDetails(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId) {
context.authenticatedUser().validateHasReadPermission("GROUP");
context.authenticatedUser().validateHasReadPermission("GROUP");
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) {
@@ -162,7 +151,7 @@ public class GroupsApiResource {
responseParameters.addAll(Arrays.asList("officeId", "allowedClients", "allowedOffices"));
GroupData groupData;
if (officeId != null){
if (officeId != null) {
groupData = this.groupReadPlatformService.retrieveNewGroupDetails(officeId);
} else {
groupData = this.groupReadPlatformService.retrieveNewGroupDetails(context.authenticatedUser().getOffice().getId());
@@ -195,12 +184,12 @@ public class GroupsApiResource {
return Response.ok().entity(entityIdentifier).build();
}
@DELETE
@Path("{groupId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public Response deleteGroup(@PathParam("groupId") final Long groupId){
public Response deleteGroup(@PathParam("groupId") final Long groupId) {
EntityIdentifier entityIdentifier = this.groupWritePlatformService.deleteGroup(groupId);
@@ -209,18 +198,15 @@ public class GroupsApiResource {
@GET
@Path("{groupId}/loans")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveGroupAccount(@PathParam("groupId") final Long groupId,
@Context final UriInfo uriInfo) {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveGroupAccount(@PathParam("groupId") final Long groupId, @Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission("GROUP");
context.authenticatedUser().validateHasReadPermission("GROUP");
Set<String> typicalResponseParameters = new HashSet<String>(
Arrays.asList("pendingApprovalLoans", "awaitingDisbursalLoans", "openLoans", "closedLoans",
"anyLoanCount", "pendingApprovalLoanCount", "awaitingDisbursalLoanCount",
"activeLoanCount", "closedLoanCount")
);
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("pendingApprovalLoans", "awaitingDisbursalLoans",
"openLoans", "closedLoans", "anyLoanCount", "pendingApprovalLoanCount", "awaitingDisbursalLoanCount", "activeLoanCount",
"closedLoanCount"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) {
@@ -230,14 +216,14 @@ public class GroupsApiResource {
GroupAccountSummaryCollectionData clientAccount = this.groupReadPlatformService.retrieveGroupAccountDetails(groupId);
return this.apiJsonSerializerService.serializeGroupAccountSummaryCollectionDataToJson(prettyPrint, responseParameters, clientAccount);
return this.apiJsonSerializerService.serializeGroupAccountSummaryCollectionDataToJson(prettyPrint, responseParameters,
clientAccount);
}
// 'g.' preffix because of ERROR 1052 (23000): Column 'column_name' in where clause is ambiguous
// 'g.' preffix because of ERROR 1052 (23000): Column 'column_name' in where
// clause is ambiguous
// caused by the same name of columns in m_office and m_group tables
private String getGroupExtraCriteria(String sqlSearch, Long officeId,
String externalId, String name,
String hierarchy){
private String getGroupExtraCriteria(String sqlSearch, Long officeId, String externalId, String name, String hierarchy) {
String extraCriteria = "";
@@ -267,8 +253,6 @@ public class GroupsApiResource {
extraCriteria = extraCriteria.substring(4);
}
//logger.info("extraCriteria; " + extraCriteria);
return extraCriteria;
}
}
@@ -752,7 +752,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
// add transaction entry for each interest posting
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.postInterest(null,
nextInterestPostingDate, futureValueOnMaturity.minus(deposit));
depositaccountTransaction.updateAccount(this);
this.depositaccountTransactions.add(depositaccountTransaction);
} else {