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() { public boolean isClientIdentifierResource() {
return this.resource.toUpperCase().startsWith("CLIENTS") && this.resource.toUpperCase().endsWith("IDENTIFIERS"); 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 ChargeDefinitionCommandHandler chargeDefinitionCommandHandler;
private final LoanProductCommandHandler loanProductCommandHandler; private final LoanProductCommandHandler loanProductCommandHandler;
private final ClientIdentifierCommandHandler clientIdentifierCommandHandler; private final ClientIdentifierCommandHandler clientIdentifierCommandHandler;
private final ClientNoteCommandHandler clientNoteCommandHandler;
@Autowired @Autowired
public CommandSourceHandlerDelegator(final PlatformSecurityContext context, public CommandSourceHandlerDelegator(final PlatformSecurityContext context,
final ClientCommandHandler clientCommandHandler, final ClientCommandHandler clientCommandHandler,
final ClientIdentifierCommandHandler clientIdentifierCommandHandler, final ClientIdentifierCommandHandler clientIdentifierCommandHandler,
final ClientNoteCommandHandler clientNoteCommandHandler,
final RoleCommandHandler roleCommandHandler, final RoleCommandHandler roleCommandHandler,
final PermissionsCommandHandler permissionCommandHandler, final PermissionsCommandHandler permissionCommandHandler,
final UserCommandHandler userCommandHandler, final UserCommandHandler userCommandHandler,
@@ -45,6 +47,7 @@ public class CommandSourceHandlerDelegator {
this.context = context; this.context = context;
this.clientCommandHandler = clientCommandHandler; this.clientCommandHandler = clientCommandHandler;
this.clientIdentifierCommandHandler = clientIdentifierCommandHandler; this.clientIdentifierCommandHandler = clientIdentifierCommandHandler;
this.clientNoteCommandHandler = clientNoteCommandHandler;
this.roleCommandHandler = roleCommandHandler; this.roleCommandHandler = roleCommandHandler;
this.permissionCommandHandler = permissionCommandHandler; this.permissionCommandHandler = permissionCommandHandler;
this.userCommandHandler = userCommandHandler; this.userCommandHandler = userCommandHandler;
@@ -66,6 +69,8 @@ public class CommandSourceHandlerDelegator {
commandSourceResult = clientCommandHandler.handleCommandWithSupportForRollback(commandSource); commandSourceResult = clientCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isClientIdentifierResource()) { } else if (commandSource.isClientIdentifierResource()) {
commandSourceResult = clientIdentifierCommandHandler.handleCommandWithSupportForRollback(commandSource); commandSourceResult = clientIdentifierCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isClientNoteResource()) {
commandSourceResult = clientNoteCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isRoleResource()) { } else if (commandSource.isRoleResource()) {
commandSourceResult = roleCommandHandler.handleCommandWithSupportForRollback(commandSource); commandSourceResult = roleCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isPermissionResource()) { } else if (commandSource.isPermissionResource()) {
@@ -102,6 +107,8 @@ public class CommandSourceHandlerDelegator {
commandSourceResult = clientCommandHandler.handleCommandForCheckerApproval(existingCommandSource); commandSourceResult = clientCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else if (existingCommandSource.isClientIdentifierResource()) { } else if (existingCommandSource.isClientIdentifierResource()) {
commandSourceResult = clientIdentifierCommandHandler.handleCommandWithSupportForRollback(existingCommandSource); commandSourceResult = clientIdentifierCommandHandler.handleCommandWithSupportForRollback(existingCommandSource);
} else if (existingCommandSource.isClientNoteResource()) {
commandSourceResult = clientNoteCommandHandler.handleCommandWithSupportForRollback(existingCommandSource);
} else if (existingCommandSource.isRoleResource()) { } else if (existingCommandSource.isRoleResource()) {
commandSourceResult = roleCommandHandler.handleCommandForCheckerApproval(existingCommandSource); commandSourceResult = roleCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else if (existingCommandSource.isPermissionResource()) { } 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.BulkTransferLoanOfficerData;
import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData; 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.GroupAccountSummaryCollectionData;
import org.mifosplatform.portfolio.group.data.GroupData; import org.mifosplatform.portfolio.group.data.GroupData;
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData; 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", private static final Set<String> GROUP_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "officeId", "name", "externalId",
"clientMembers", "allowedClients", "allowedOffices")); "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", private static final Set<String> LOAN_SCHEDULE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("periods",
"cumulativePrincipalDisbursed")); "cumulativePrincipalDisbursed"));
@@ -213,20 +208,6 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi
return helper.serializedJsonFrom(gsonDeserializer, group); 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 @Override
public String serializeLoanScheduleDataToJson(final boolean prettyPrint, final Set<String> responseParameters, public String serializeLoanScheduleDataToJson(final boolean prettyPrint, final Set<String> responseParameters,
final LoanScheduleData loanSchedule) { 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.BulkTransferLoanOfficerData;
import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData; 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.GroupAccountSummaryCollectionData;
import org.mifosplatform.portfolio.group.data.GroupData; import org.mifosplatform.portfolio.group.data.GroupData;
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData; import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
@@ -53,10 +52,6 @@ public interface PortfolioApiJsonSerializerService {
String serializeGroupDataToJson(boolean prettyPrint, Set<String> responseParameters, GroupData group); 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 serializeLoanScheduleDataToJson(boolean prettyPrint, Set<String> responseParameters, LoanScheduleData loanSchedule);
String serializeLoanTransactionDataToJson(boolean prettyPrint, Set<String> responseParameters, LoanTransactionData newTransactionData); 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.GenericResultsetData;
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeader; import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeader;
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetDataRow; 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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -28,8 +26,6 @@ import com.sun.rowset.CachedRowSetImpl;
@Service @Service
public class GenericDataServiceImpl implements GenericDataService { public class GenericDataServiceImpl implements GenericDataService {
private final static Logger logger = LoggerFactory.getLogger(GenericDataServiceImpl.class);
private final DataSource dataSource; private final DataSource dataSource;
@Autowired @Autowired
@@ -39,11 +35,11 @@ public class GenericDataServiceImpl implements GenericDataService {
} }
@Override @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 // TODO - Need to reimplement this away from Sun library - could be
// mixture of Lists and jdbcTemplate.query // mixture of Lists and jdbcTemplate.query
long startTime = System.currentTimeMillis(); // long startTime = System.currentTimeMillis();
Connection db_connection = null; Connection db_connection = null;
Statement db_statement = null; Statement db_statement = null;
CachedRowSet crs = null; CachedRowSet crs = null;
@@ -63,15 +59,15 @@ public class GenericDataServiceImpl implements GenericDataService {
} }
long elapsed = System.currentTimeMillis() - startTime; // long elapsed = System.currentTimeMillis() - startTime;
//logger.info("Elapsed Time: " + elapsed + " SQL: " + sql); // logger.info("Elapsed Time: " + elapsed + " SQL: " + sql);
return crs; return crs;
} }
@Override @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; Connection db_connection = null;
Statement db_statement = null; Statement db_statement = null;
try { try {
@@ -84,8 +80,9 @@ public class GenericDataServiceImpl implements GenericDataService {
dbClose(db_statement, db_connection); dbClose(db_statement, db_connection);
} }
long elapsed = System.currentTimeMillis() - startTime; // long elapsed = System.currentTimeMillis() - startTime;
//logger.info("Elapsed Time FOR UPDATE: " + elapsed + " SQL: " + sql); // logger.info("Elapsed Time FOR UPDATE: " + elapsed + " SQL: " +
// sql);
} }
@Override @Override
@@ -129,7 +126,7 @@ public class GenericDataServiceImpl implements GenericDataService {
} }
@Override @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 // JPW - this replace may / may not be any better or quicker than the
// apache stringutils equivalent. It works, but if someone shows the // apache stringutils equivalent. It works, but if someone shows the
// apache one to be about the same then this can be removed. // apache one to be about the same then this can be removed.
@@ -147,7 +144,7 @@ public class GenericDataServiceImpl implements GenericDataService {
} }
@Override @Override
public String wrapSQL(String sql) { public String wrapSQL(final String sql) {
// wrap sql to prevent JDBC sql errors, prevent malicious sql and a // wrap sql to prevent JDBC sql errors, prevent malicious sql and a
// CachedRowSetImpl bug // CachedRowSetImpl bug
@@ -158,21 +155,21 @@ public class GenericDataServiceImpl implements GenericDataService {
} }
@Override @Override
public String generateJsonFromGenericResultsetData(GenericResultsetData grs) { public String generateJsonFromGenericResultsetData(final GenericResultsetData grs) {
StringBuffer writer = new StringBuffer(); StringBuffer writer = new StringBuffer();
writer.append("["); writer.append("[");
List<ResultsetColumnHeader> columnHeaders = grs.getColumnHeaders(); 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<ResultsetDataRow> data = grs.getData();
List<String> row; List<String> row;
Integer rSize; Integer rSize;
String currColType; String currColType;
String currVal; String currVal;
//logger.info("NO. of Rows: " + data.size()); // logger.info("NO. of Rows: " + data.size());
for (int i = 0; i < data.size(); i++) { for (int i = 0; i < data.size(); i++) {
writer.append("\n{"); writer.append("\n{");
@@ -212,7 +209,7 @@ public class GenericDataServiceImpl implements GenericDataService {
} }
private void dbClose(Statement db_statement, Connection db_connection) { private void dbClose(Statement db_statement, Connection db_connection) {
//logger.debug("dbClose"); // logger.debug("dbClose");
try { try {
if (db_statement != null) { if (db_statement != null) {
db_statement.close(); db_statement.close();
@@ -45,9 +45,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
private GenericDataService genericDataService; private GenericDataService genericDataService;
@Override @Override
public List<DatatableData> retrieveDatatableNames(String appTable) { public List<DatatableData> retrieveDatatableNames(final String appTable) {
long startTime = System.currentTimeMillis(); // long startTime = System.currentTimeMillis();
String andClause; String andClause;
if (appTable == null) { if (appTable == null) {
@@ -76,16 +76,17 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg); throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg);
} }
long elapsed = System.currentTimeMillis() - startTime; // long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING retrieveDatatableNames: Elapsed Time: " + elapsed); // logger.info("FINISHING retrieveDatatableNames: Elapsed Time: " +
// elapsed);
return datatables; return datatables;
} }
@Override @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); validateAppTable(appTable);
@@ -115,14 +116,15 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
genericDataService.updateSQL(sql, "SQL: " + sql); genericDataService.updateSQL(sql, "SQL: " + sql);
long elapsed = System.currentTimeMillis() - startTime; // long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING registerDatatable: Elapsed Time: " + elapsed + " - datatable: " + datatable // logger.info("FINISHING registerDatatable: Elapsed Time: " +
// + " application table: " + appTable); // elapsed + " - datatable: " + datatable
// + " application table: " + appTable);
} }
@Override @Override
public void deregisterDatatable(String datatable) { public void deregisterDatatable(final String datatable) {
long startTime = System.currentTimeMillis(); // long startTime = System.currentTimeMillis();
// TODO - put in batch command later // 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 + "'"; sql = "delete from x_registered_table where registered_table_name = '" + datatable + "'";
genericDataService.updateSQL(sql, "SQL: " + sql); genericDataService.updateSQL(sql, "SQL: " + sql);
long elapsed = System.currentTimeMillis() - startTime; // long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING deregisterDatatable: Elapsed Time: " + elapsed + " - datatable: " + datatable); // logger.info("FINISHING deregisterDatatable: Elapsed Time: " +
// elapsed + " - datatable: " + datatable);
} }
@Override @Override
public void newDatatableEntry(String datatable, Long appTableId, Map<String, String> queryParams) { public void newDatatableEntry(final String datatable, final Long appTableId, final Map<String, String> queryParams) {
long startTime = System.currentTimeMillis(); // long startTime = System.currentTimeMillis();
String appTable = getWithinScopeApplicationTableName(datatable, appTableId); String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
@@ -155,15 +158,16 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
genericDataService.updateSQL(sql, "SQL: " + sql); genericDataService.updateSQL(sql, "SQL: " + sql);
long elapsed = System.currentTimeMillis() - startTime; // long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING newDatatableEntry: Elapsed Time: " + elapsed + " - datatable: " + datatable + " id: " // logger.info("FINISHING newDatatableEntry: Elapsed Time: " +
// + appTableId); // elapsed + " - datatable: " + datatable + " id: "
// + appTableId);
} }
@Override @Override
public void updateDatatableEntryOnetoOne(String datatable, Long appTableId, Map<String, String> queryParams) { public void updateDatatableEntryOnetoOne(final String datatable, final Long appTableId, final Map<String, String> queryParams) {
long startTime = System.currentTimeMillis(); // long startTime = System.currentTimeMillis();
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, null); GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, null);
@@ -176,20 +180,23 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
String fkName = getFKField(getApplicationTableName(datatable)); String fkName = getFKField(getApplicationTableName(datatable));
String sql = getUpdateSql(grs, datatable, fkName, appTableId, queryParams); String sql = getUpdateSql(grs, datatable, fkName, appTableId, queryParams);
if (sql != null) if (sql != null) {
genericDataService.updateSQL(sql, "SQL: " + sql); genericDataService.updateSQL(sql, "SQL: " + sql);
else } else {
logger.info("No Changes"); logger.info("No Changes");
}
long elapsed = System.currentTimeMillis() - startTime; // long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: " + elapsed + " - datatable: " + datatable + fkName // logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: "
// + ": " + appTableId); // + elapsed + " - datatable: " + datatable + fkName
// + ": " + appTableId);
} }
@Override @Override
public void updateDatatableEntryOnetoMany(String datatable, Long appTableId, Long datatableId, Map<String, String> queryParams) { public void updateDatatableEntryOnetoMany(final String datatable, final Long appTableId, final Long datatableId,
long startTime = System.currentTimeMillis(); final Map<String, String> queryParams) {
// long startTime = System.currentTimeMillis();
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, datatableId); GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, datatableId);
@@ -197,19 +204,21 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
String sql = getUpdateSql(grs, datatable, "id", datatableId, queryParams); String sql = getUpdateSql(grs, datatable, "id", datatableId, queryParams);
if (sql != null) if (sql != null) {
genericDataService.updateSQL(sql, "SQL: " + sql); genericDataService.updateSQL(sql, "SQL: " + sql);
else } else {
logger.info("No Changes"); logger.info("No Changes");
}
long elapsed = System.currentTimeMillis() - startTime; // long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: " + elapsed + " - datatable: " + datatable + " id: " // logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: "
// + datatableId); // + elapsed + " - datatable: " + datatable + " id: "
// + datatableId);
} }
@Override @Override
public void deleteDatatableEntries(String datatable, Long appTableId) { public void deleteDatatableEntries(final String datatable, final Long appTableId) {
long startTime = System.currentTimeMillis(); // long startTime = System.currentTimeMillis();
String appTable = getWithinScopeApplicationTableName(datatable, appTableId); String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
@@ -217,15 +226,16 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
genericDataService.updateSQL(sql, "SQL: " + sql); genericDataService.updateSQL(sql, "SQL: " + sql);
long elapsed = System.currentTimeMillis() - startTime; // long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING deleteDatatableEntries: Elapsed Time: " + elapsed + " - datatable: " + datatable // logger.info("FINISHING deleteDatatableEntries: Elapsed Time: " +
// + " App Table Id: " + appTableId); // elapsed + " - datatable: " + datatable
// + " App Table Id: " + appTableId);
} }
@Override @Override
public void deleteDatatableEntry(String datatable, Long appTableId, Long datatableId) { public void deleteDatatableEntry(final String datatable, final Long appTableId, final Long datatableId) {
long startTime = System.currentTimeMillis(); // long startTime = System.currentTimeMillis();
getWithinScopeApplicationTableName(datatable, appTableId); getWithinScopeApplicationTableName(datatable, appTableId);
@@ -233,16 +243,19 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
genericDataService.updateSQL(sql, "SQL: " + sql); genericDataService.updateSQL(sql, "SQL: " + sql);
long elapsed = System.currentTimeMillis() - startTime; // long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING deleteDatatableEntry: Elapsed Time: " + elapsed + " - datatable: " + datatable // logger.info("FINISHING deleteDatatableEntry: Elapsed Time: " +
// + " App Table Id: " + appTableId + " Data Table Id: " + datatableId); // elapsed + " - datatable: " + datatable
// + " App Table Id: " + appTableId + " Data Table Id: " +
// datatableId);
} }
@Override @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); String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
@@ -262,14 +275,15 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
List<ResultsetDataRow> result = fillDatatableResultSetDataRows(sql); List<ResultsetDataRow> result = fillDatatableResultSetDataRows(sql);
long elapsed = System.currentTimeMillis() - startTime; // long elapsed = System.currentTimeMillis() - startTime;
//logger.info("FINISHING DATATABLE: " + datatable + " Elapsed Time: " + elapsed + " SQL: " + sql); // logger.info("FINISHING DATATABLE: " + datatable +
// " Elapsed Time: " + elapsed + " SQL: " + sql);
return new GenericResultsetData(columnHeaders, result); 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; 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); 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; String dataScopeCriteria = null;
/* /*
* unfortunately have to, one way or another, be able to restrict data * 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_client")) return;
if (appTable.equalsIgnoreCase("m_loan")) 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 + "'"; String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'";
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql); 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 // TODO - only used for update... can probably remove this after as its
// a reread // a reread
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'"; 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"; 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" 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 + " 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); throw new DataTableNotFoundException(datatable);
} }
private List<ResultsetColumnHeader> getDatatableResultsetColumnHeaders(String datatable) { private List<ResultsetColumnHeader> getDatatableResultsetColumnHeaders(final String datatable) {
CachedRowSet columnDefinitions = getDatatableMetaData(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); int codePosition = rsch.getColumnName().indexOf(code_suffix);
if (codePosition > 0) { if (codePosition > 0) {
String codeName = rsch.getColumnName().substring(0, codePosition); 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, private String getAddSql(final List<ResultsetColumnHeader> columnHeaders, final String datatable, final String fkName,
Map<String, String> queryParams) { 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 pValueWrite = "";
String addSql = ""; String addSql = "";
@@ -503,10 +517,10 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return addSql; return addSql;
} }
private String getUpdateSql(GenericResultsetData grs, String datatable, String keyFieldName, Long keyFieldValue, private String getUpdateSql(final GenericResultsetData grs, final String datatable, final String keyFieldName,
Map<String, String> queryParams) { 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 // just updating fields that have changed since pre-update read - though
// its possible these values are different from the page the user was // its possible these values are different from the page the user was
@@ -545,7 +559,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return sql; 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> affectedColumns = getAffectedColumns(grs.getColumnHeaders(), queryParams, fkName);
Map<String, String> affectedAndChangedColumns = new HashMap<String, String>(); Map<String, String> affectedAndChangedColumns = new HashMap<String, String>();
@@ -561,7 +576,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return affectedAndChangedColumns; 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(); 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"); 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, private Map<String, String> getAffectedColumns(final List<ResultsetColumnHeader> columnHeaders, final Map<String, String> queryParams,
String keyFieldName) { final String keyFieldName) {
String dateFormat = queryParams.get("dateFormat"); String dateFormat = queryParams.get("dateFormat");
Locale clientApplicationLocale = null; Locale clientApplicationLocale = null;
@@ -628,7 +643,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return affectedColumns; 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; String paramValue = pValue;
@@ -693,19 +709,19 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return paramValue; 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; 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; 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) && StringUtils.isEmpty(pValue)) return false;
if (StringUtils.isEmpty(currValue)) return true; if (StringUtils.isEmpty(currValue)) return true;
@@ -716,5 +732,4 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return true; 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.data.StaffData;
import org.mifosplatform.organisation.staff.serialization.StaffCommandFromApiJsonDeserializer; import org.mifosplatform.organisation.staff.serialization.StaffCommandFromApiJsonDeserializer;
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService; 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.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -42,8 +40,6 @@ import org.springframework.stereotype.Component;
@Scope("singleton") @Scope("singleton")
public class StaffApiResource { public class StaffApiResource {
private final static Logger logger = LoggerFactory.getLogger(StaffApiResource.class);
/** /**
* The set of parameters that are supported in response for {@link CodeData} * The set of parameters that are supported in response for {@link CodeData}
*/ */
@@ -155,7 +151,6 @@ public class StaffApiResource {
if (StringUtils.isNotBlank(extraCriteria)) { if (StringUtils.isNotBlank(extraCriteria)) {
extraCriteria = extraCriteria.substring(4); extraCriteria = extraCriteria.substring(4);
} }
//logger.debug("extraCriteria; " + extraCriteria);
return 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.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.data.OfficeLookup; import org.mifosplatform.organisation.office.data.OfficeLookup;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService; import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.mifosplatform.portfolio.client.command.NoteCommand;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData; import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData;
import org.mifosplatform.portfolio.client.data.ClientData; 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.exception.ImageNotFoundException;
import org.mifosplatform.portfolio.client.serialization.ClientCommandFromApiJsonDeserializer; import org.mifosplatform.portfolio.client.serialization.ClientCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.mifosplatform.portfolio.client.service.ClientWritePlatformService; 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.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -63,8 +59,6 @@ import com.sun.jersey.multipart.FormDataParam;
@Scope("singleton") @Scope("singleton")
public class ClientsApiResource { 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", private final Set<String> CLIENT_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "officeId", "officeName", "externalId",
"firstname", "lastname", "joinedDate", "displayName", "clientOrBusinessName", "allowedOffices", "imagePresent")); "firstname", "lastname", "joinedDate", "displayName", "clientOrBusinessName", "allowedOffices", "imagePresent"));
@@ -85,7 +79,7 @@ public class ClientsApiResource {
final ClientWritePlatformService clientWritePlatformService, final OfficeReadPlatformService officeReadPlatformService, final ClientWritePlatformService clientWritePlatformService, final OfficeReadPlatformService officeReadPlatformService,
final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer, final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioApiDataConversionService apiDataConversionService, final PortfolioApiDataConversionService apiDataConversionService,
final PortfolioApiJsonSerializerService apiJsonSerializerService, final PortfolioApiJsonSerializerService apiJsonSerializerService,
final PortfolioCommandsReadPlatformService commandsReadPlatformService, final PortfolioCommandsReadPlatformService commandsReadPlatformService,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
@@ -158,7 +152,7 @@ public class ClientsApiResource {
extraCriteria = extraCriteria.substring(4); extraCriteria = extraCriteria.substring(4);
} }
//logger.info("extraCriteria; " + extraCriteria); // logger.info("extraCriteria; " + extraCriteria);
return extraCriteria; return extraCriteria;
} }
@@ -260,8 +254,9 @@ public class ClientsApiResource {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "UPDATE_CLIENT"); final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "UPDATE_CLIENT");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENT", allowedPermissions); 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, final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "clients", clientId,
commandSerializedAsJson); commandSerializedAsJson);
@@ -299,66 +294,6 @@ public class ClientsApiResource {
clientAccount); 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 * 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") @Table(name = "m_note")
public class Note extends AbstractAuditableCustom<AppUser, Long> { public class Note extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne @ManyToOne
@JoinColumn(name = "client_id", nullable = false) @JoinColumn(name = "client_id", nullable = false)
private final Client client; 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;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Column(name = "note", length=1000) @ManyToOne
private String note; @JoinColumn(name = "loan_id", nullable = true)
private Loan loan;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Column(name = "note_type_enum") @ManyToOne
private Integer noteTypeId; @JoinColumn(name = "loan_transaction_id", nullable = true)
private LoanTransaction loanTransaction;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ManyToOne @Column(name = "note", length = 1000)
@JoinColumn(name = "deposit_account_id", nullable = true) private String note;
private DepositAccount depositAccount;
@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 { 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 Integer value;
private String code; 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() { public String getCode() {
return code; return code;
} }
public static NoteType parse(Integer id) { public static NoteType parse(Integer id) {
NoteType right = null; // Default NoteType right = null; // Default
for (NoteType item : NoteType.values()) { for (NoteType item : NoteType.values()) {
if (item.getValue().intValue() == id.intValue()) { if (item.getValue().intValue() == id.intValue()) {
right = item; right = item;
@@ -70,38 +77,38 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
} }
public static Note clientNote(Client client, String note) { 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) { private Note(Client client, String note) {
this.client = client; this.client = client;
this.note = note; this.note = note;
this.noteTypeId = NoteType.CLIENT.getValue(); this.noteTypeId = NoteType.CLIENT.getValue();
} }
private Note(Loan loan, String note) { private Note(Loan loan, String note) {
this.loan = loan; this.loan = loan;
this.client = loan.client(); this.client = loan.client();
this.note = note; this.note = note;
this.noteTypeId = NoteType.LOAN.getValue(); this.noteTypeId = NoteType.LOAN.getValue();
} }
private Note(Loan loan, LoanTransaction loanTransaction, String note) { private Note(Loan loan, LoanTransaction loanTransaction, String note) {
this.loan = loan; this.loan = loan;
this.loanTransaction = loanTransaction; this.loanTransaction = loanTransaction;
this.client = loan.client(); this.client = loan.client();
this.note = note; this.note = note;
this.noteTypeId = NoteType.LOAN_TRANSACTION.getValue(); this.noteTypeId = NoteType.LOAN_TRANSACTION.getValue();
} }
protected Note() { protected Note() {
this.client = null; this.client = null;
this.loan = null; this.loan = null;
@@ -110,22 +117,22 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
this.noteTypeId = null; this.noteTypeId = null;
} }
public Note(DepositAccount account, String note) { public Note(DepositAccount account, String note) {
this.depositAccount=account; // this.depositAccount = account;
this.client = account.client(); this.client = account.client();
this.note = note; this.note = note;
this.noteTypeId = NoteType.DEPOSIT.getValue(); this.noteTypeId = NoteType.DEPOSIT.getValue();
} }
public void update(final String note) { public void update(final String note) {
this.note = note; this.note = note;
} }
public boolean isNotAgainstClientWithIdOf(Long clientId) { public boolean isNotAgainstClientWithIdOf(Long clientId) {
return !this.client.identifiedBy(clientId); return !this.client.identifiedBy(clientId);
} }
public static Note depositNote(DepositAccount account, String noteText) { public static Note depositNote(DepositAccount account, String noteText) {
return new Note(account,noteText); return new Note(account, noteText);
} }
} }
@@ -6,6 +6,7 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer; import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer; import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
@@ -21,7 +22,7 @@ import com.google.gson.reflect.TypeToken;
* 's. * 's.
*/ */
@Component @Component
public final class ClientIdentifierCommandFromApiJsonDeserializer implements FromApiJsonDeserializer<ClientIdentifierCommand> { public final class ClientIdentifierCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<ClientIdentifierCommand> {
/** /**
* The parameters supported for this command. * The parameters supported for this command.
@@ -30,44 +31,27 @@ public final class ClientIdentifierCommandFromApiJsonDeserializer implements Fro
"description")); "description"));
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
private final CommandSerializer commandSerializerService;
private final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer; private final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final CommandSerializer commandSerializerService;
@Autowired @Autowired
public ClientIdentifierCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper, public ClientIdentifierCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper,
final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer, final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final CommandSerializer commandSerializerService) { final CommandSerializer commandSerializerService) {
super(commandSerializerService);
this.fromApiJsonHelper = fromApiJsonHelper; this.fromApiJsonHelper = fromApiJsonHelper;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer; this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.commandSerializerService = commandSerializerService; this.commandSerializerService = commandSerializerService;
} }
@Override @Override
public ClientIdentifierCommand commandFromApiJson(final String json) { public ClientIdentifierCommand commandFromApiJson(final Long clientIdentifierId, final String json) {
return commandFromApiJson(null, json);
}
@Override
public ClientIdentifierCommand commandFromApiJson(final Long clientId, final String json) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
return this.commandFromCommandJsonDeserializer.commandFromCommandJson(clientId, json); return this.commandFromCommandJsonDeserializer.commandFromCommandJson(clientIdentifierId, 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);
} }
public String serializedCommandJsonFromApiJsonWithSubResource(final String json, final Long clientId) { 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.infrastructure.core.domain.Base64EncodedImage;
import org.mifosplatform.portfolio.client.command.ClientCommand; import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand; 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; import org.springframework.security.access.prepost.PreAuthorize;
public interface ClientWritePlatformService { public interface ClientWritePlatformService {
@@ -26,11 +26,9 @@ public interface ClientWritePlatformService {
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'DELETE_CLIENTIMAGE')") @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'DELETE_CLIENTIMAGE')")
EntityIdentifier deleteClientImage(Long clientId); EntityIdentifier deleteClientImage(Long clientId);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_CLIENTNOTE')") EntityIdentifier addClientNote(ClientNoteCommand command);
EntityIdentifier addClientNote(NoteCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'UPDATE_CLIENTNOTE')") EntityIdentifier updateNote(ClientNoteCommand command);
EntityIdentifier updateNote(NoteCommand command);
Long addClientIdentifier(ClientIdentifierCommand 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.ClientCommandValidator;
import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand; import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand;
import org.mifosplatform.portfolio.client.command.ClientIdentifierCommandValidator; 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.Client;
import org.mifosplatform.portfolio.client.domain.ClientIdentifier; import org.mifosplatform.portfolio.client.domain.ClientIdentifier;
import org.mifosplatform.portfolio.client.domain.ClientIdentifierRepository; import org.mifosplatform.portfolio.client.domain.ClientIdentifierRepository;
@@ -166,7 +166,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional @Transactional
@Override @Override
public EntityIdentifier addClientNote(final NoteCommand command) { public EntityIdentifier addClientNote(final ClientNoteCommand command) {
context.authenticatedUser(); context.authenticatedUser();
@@ -182,7 +182,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional @Transactional
@Override @Override
public EntityIdentifier updateNote(final NoteCommand command) { public EntityIdentifier updateNote(final ClientNoteCommand command) {
context.authenticatedUser(); 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.data.GroupData;
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService; import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
import org.mifosplatform.portfolio.group.service.GroupWritePlatformService; 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.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -45,8 +43,6 @@ import org.springframework.stereotype.Component;
@Scope("singleton") @Scope("singleton")
public class GroupsApiResource { public class GroupsApiResource {
private final static Logger logger = LoggerFactory.getLogger(GroupsApiResource.class);
@Autowired @Autowired
private GroupReadPlatformService groupReadPlatformService; private GroupReadPlatformService groupReadPlatformService;
@@ -62,27 +58,23 @@ public class GroupsApiResource {
@Autowired @Autowired
private OfficeReadPlatformService officeReadPlatformService; private OfficeReadPlatformService officeReadPlatformService;
@Autowired @Autowired
private PortfolioApiJsonSerializerService apiJsonSerializerService; private PortfolioApiJsonSerializerService apiJsonSerializerService;
@Autowired @Autowired
private PlatformSecurityContext context; private PlatformSecurityContext context;
private static final Set<String> typicalResponseParameters = new HashSet<String>( private static final Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "officeId", "name", "externalId",
Arrays.asList("id", "officeId", "name", "externalId", "clientMembers") "clientMembers"));
);
@GET @GET
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllGroups(@Context final UriInfo uriInfo, public String retrieveAllGroups(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch,
@QueryParam("sqlSearch") final String sqlSearch, @QueryParam("officeId") final Long officeId, @QueryParam("externalId") final String externalId,
@QueryParam("officeId") final Long officeId, @QueryParam("name") final String name, @QueryParam("underHierarchy") final String hierarchy) {
@QueryParam("externalId") final String externalId,
@QueryParam("name") final String name, context.authenticatedUser().validateHasReadPermission("GROUP");
@QueryParam("underHierarchy") final String hierarchy){
context.authenticatedUser().validateHasReadPermission("GROUP");
final String extraCriteria = getGroupExtraCriteria(sqlSearch, officeId, externalId, name, hierarchy); final String extraCriteria = getGroupExtraCriteria(sqlSearch, officeId, externalId, name, hierarchy);
@@ -102,14 +94,12 @@ public class GroupsApiResource {
@Path("{groupId}") @Path("{groupId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveGroupData(@Context final UriInfo uriInfo, public String retrieveGroupData(@Context final UriInfo uriInfo, @PathParam("groupId") final Long groupId,
@PathParam("groupId") final Long groupId, @QueryParam("officeId") final Long officeId) {
@QueryParam("officeId") final Long officeId) {
context.authenticatedUser().validateHasReadPermission("GROUP"); context.authenticatedUser().validateHasReadPermission("GROUP");
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
.getQueryParameters());
if (responseParameters.isEmpty()) { if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters); responseParameters.addAll(typicalResponseParameters);
} }
@@ -124,34 +114,33 @@ public class GroupsApiResource {
group = new GroupData(group, clientMembers, availableClients, allowedOffices); group = new GroupData(group, clientMembers, availableClients, allowedOffices);
boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
if (template) { if (template) {
responseParameters.add("allowedClients"); responseParameters.add("allowedClients");
responseParameters.add("allowedOffices"); responseParameters.add("allowedOffices");
if (officeId != null){ if (officeId != null) {
availableClients = this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(officeId); availableClients = this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(officeId);
} else { } else {
availableClients = this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(group.getOfficeId()); 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); return this.apiJsonSerializerService.serializeGroupDataToJson(prettyPrint, responseParameters, group);
} }
@GET @GET
@Path("template") @Path("template")
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({MediaType.APPLICATION_JSON}) @Produces({ MediaType.APPLICATION_JSON })
public String newGroupDetails(@Context final UriInfo uriInfo, public String newGroupDetails(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId) {
@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()) { if (responseParameters.isEmpty()) {
@@ -162,7 +151,7 @@ public class GroupsApiResource {
responseParameters.addAll(Arrays.asList("officeId", "allowedClients", "allowedOffices")); responseParameters.addAll(Arrays.asList("officeId", "allowedClients", "allowedOffices"));
GroupData groupData; GroupData groupData;
if (officeId != null){ if (officeId != null) {
groupData = this.groupReadPlatformService.retrieveNewGroupDetails(officeId); groupData = this.groupReadPlatformService.retrieveNewGroupDetails(officeId);
} else { } else {
groupData = this.groupReadPlatformService.retrieveNewGroupDetails(context.authenticatedUser().getOffice().getId()); groupData = this.groupReadPlatformService.retrieveNewGroupDetails(context.authenticatedUser().getOffice().getId());
@@ -195,12 +184,12 @@ public class GroupsApiResource {
return Response.ok().entity(entityIdentifier).build(); return Response.ok().entity(entityIdentifier).build();
} }
@DELETE @DELETE
@Path("{groupId}") @Path("{groupId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ 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); EntityIdentifier entityIdentifier = this.groupWritePlatformService.deleteGroup(groupId);
@@ -209,18 +198,15 @@ public class GroupsApiResource {
@GET @GET
@Path("{groupId}/loans") @Path("{groupId}/loans")
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({MediaType.APPLICATION_JSON}) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveGroupAccount(@PathParam("groupId") final Long groupId, public String retrieveGroupAccount(@PathParam("groupId") final Long groupId, @Context final UriInfo uriInfo) {
@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission("GROUP"); context.authenticatedUser().validateHasReadPermission("GROUP");
Set<String> typicalResponseParameters = new HashSet<String>( Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("pendingApprovalLoans", "awaitingDisbursalLoans",
Arrays.asList("pendingApprovalLoans", "awaitingDisbursalLoans", "openLoans", "closedLoans", "openLoans", "closedLoans", "anyLoanCount", "pendingApprovalLoanCount", "awaitingDisbursalLoanCount", "activeLoanCount",
"anyLoanCount", "pendingApprovalLoanCount", "awaitingDisbursalLoanCount", "closedLoanCount"));
"activeLoanCount", "closedLoanCount")
);
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) { if (responseParameters.isEmpty()) {
@@ -230,14 +216,14 @@ public class GroupsApiResource {
GroupAccountSummaryCollectionData clientAccount = this.groupReadPlatformService.retrieveGroupAccountDetails(groupId); 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 // caused by the same name of columns in m_office and m_group tables
private String getGroupExtraCriteria(String sqlSearch, Long officeId, private String getGroupExtraCriteria(String sqlSearch, Long officeId, String externalId, String name, String hierarchy) {
String externalId, String name,
String hierarchy){
String extraCriteria = ""; String extraCriteria = "";
@@ -267,8 +253,6 @@ public class GroupsApiResource {
extraCriteria = extraCriteria.substring(4); extraCriteria = extraCriteria.substring(4);
} }
//logger.info("extraCriteria; " + extraCriteria);
return extraCriteria; return extraCriteria;
} }
} }
@@ -752,7 +752,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
// add transaction entry for each interest posting // add transaction entry for each interest posting
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.postInterest(null, DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.postInterest(null,
nextInterestPostingDate, futureValueOnMaturity.minus(deposit)); nextInterestPostingDate, futureValueOnMaturity.minus(deposit));
depositaccountTransaction.updateAccount(this); depositaccountTransaction.updateAccount(this);
this.depositaccountTransactions.add(depositaccountTransaction); this.depositaccountTransactions.add(depositaccountTransaction);
} else { } else {