diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index 6bb67ba0c..1a85d8ed8 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -144,8 +144,6 @@ function getBaseURL(docURL)
- - @@ -2221,178 +2219,6 @@ Request Body:{ - -   -
-
-

Additional Fields (Deprecated)

-

Note: this API is now superceded by the datatables API and will be removed very soon.

-

- In Mifos X, any number of "Sets" of "Additional Fields" can be configured for a Mifos X database table ("Type"). -

-

For example, portfolio_client is the database table that holds client data. Typically, MFI's want more client related fields than is provided by Mifos X out-of-the-box. - The MFI might add a Set called "Additional Info" containing some fields that are typically input when creating a client. - They might then add another Set called "Highly Improbable Info" containing some fields that are only input in exceptional - circumstances. -

-

- The additional fields resource allows you to retrieve and update any Additional Fields data that has been configured in Mifos X. -

-

- The Mifos X Individual Lending client application uses a JQuery plugin called stretchydata which, itself, uses this - additional fields resource to provide a pretty flexible additional fields User Interface (UI). -

-
-
- - -   -
-
-

List Additional Fields Sets

-

- Lists the Sets of additional fields have been defined in Mifos X. -

- -
Arguments
-
-
type
-
optional
-
The Additional Fields Type (Mifos X database table) to restrict the output to
-
-

Example Requests:

-
additionalfields?type=m_client
-

-
additionalfields
-
-
- GET https://Domain Name/api/v1/additionalfields - [ { - "id" : 1, - "name" : "Additional Information", - "type" : "portfolio_client" -}, { - "id" : 8, - "name" : "Additional Information", - "type" : "portfolio_loan" -}, { - "id" : 9, - "name" : "Highly Improbable Info", - "type" : "portfolio_client" -} ] - -
-
- - -   -
-
-

Retrieve Additional Fields

-

- Returns the Set of Additional Fields data for the ID provided. The ID is the id field of the Type table e.g. portfolio_client might have an id value of 4. The output is a JSON formatted "Generic Resultset". The Generic Resultset contains Column Heading as well as Data information. The Column Heading information may include allowed values (columnValues array). -

-

Example Request: -

additionalfields/m_client/Additional Information/2
-

-
-
- GET https://Domain Name/api/v1/additionalfields/{type}/{set}/{id} - { - "columnHeaders" : [ { - "columnName" : "Ethnic Group", - "columnType" : "String", - "columnLength" : 50, - "columnDisplayType" : "List", - "columnValues" : [ "Bedouin", "Berber", "Italian", "Miknasa", "Mrazig", "Other", "Unknown" ] - }, { - "columnName" : "Ethnic Group Other", - "columnType" : "String", - "columnLength" : 50, - "columnDisplayType" : null, - "columnValues" : [ ] - }, { - "columnName" : "Household Location", - "columnType" : "String", - "columnLength" : 50, - "columnDisplayType" : "List", - "columnValues" : [ "East Sikkim", "North Sikkim", "South Sikkim", "West Sikkim", "Other" ] - }, { - "columnName" : "Household Location Other", - "columnType" : "String", - "columnLength" : 50, - "columnDisplayType" : null, - "columnValues" : [ ] - }, { - "columnName" : "Religion", - "columnType" : "String", - "columnLength" : 50, - "columnDisplayType" : "List", - "columnValues" : [ "Protestant", "Catholic", "Muslim", "Animist", "Atheist", "Other", "Unknown" ] - }, { - "columnName" : "Religion Other", - "columnType" : "String", - "columnLength" : 50, - "columnDisplayType" : null, - "columnValues" : [ ] - }, { - "columnName" : "Knowledge of Person", - "columnType" : "String", - "columnLength" : 50, - "columnDisplayType" : "List", - "columnValues" : [ "Staff member", "Spouse of staff member", "Son/daughter of staff member", "Friend of staff member", "Not known by any staff member", "Other" ] - }, { - "columnName" : "Gender", - "columnType" : "String", - "columnLength" : 10, - "columnDisplayType" : "List", - "columnValues" : [ "Female", "Male" ] - }, { - "columnName" : "Whois", - "columnType" : "Text", - "columnLength" : null, - "columnDisplayType" : null, - "columnValues" : [ ] - } ], - "data" : [ { - "row" : [ "Bedouin", null, "East Sikkim", null, "Animist", "Agnostic", "Friend of staff member", "Female", "A person of honesty & clear thought" ] - } ] -} - -
-
-   -
-
-

Update Additional Fields

-

- Updates (or creates) the Set of Additional Fields data for the ID provided. The ID is the id field of the Type table e.g. portfolio_client might have an id value of 4. -

-
-
- POST https://Domain Name/api/v1/additionalfields/{type}/{set}/{id} - POST additionalfields/portfolio_client/Additional Information/2 -Content-Type: application/json -Request Body: -{ - "Ethnic_Group":"Berber", - "Ethnic_Group_Other":"", - "Household_Location":"East Sikkim", - "Household_Location_Other":"", - "Religion":"Animist", - "Religion_Other":"jjjjjjj", - "Knowledge_of_Person":"Son/daughter of staff member", - "Gender":"Female", - "Whois":"its\r\nme of\r\ncourse\r\nyes\r\nend and the end of it all" -} - - { - "entityId": 2 -} - -
-
-  
@@ -3483,8 +3309,6 @@ Request body:
- - diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/AdditionalFieldsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/AdditionalFieldsApiResource.java deleted file mode 100644 index 1c72c8bec..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/AdditionalFieldsApiResource.java +++ /dev/null @@ -1,174 +0,0 @@ -package org.mifosng.platform.api; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; -import javax.ws.rs.core.UriInfo; - -import org.codehaus.jettison.json.JSONArray; -import org.codehaus.jettison.json.JSONException; -import org.codehaus.jettison.json.JSONObject; -import org.mifosng.platform.InvalidSqlException; -import org.mifosng.platform.api.data.AdditionalFieldsSetData; -import org.mifosng.platform.api.data.ApiParameterError; -import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.api.data.GenericResultsetData; -import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.exceptions.NoAuthorizationException; -import org.mifosng.platform.exceptions.PlatformApiDataValidationException; -import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.noncore.AdditionalFieldsService; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.mifosng.platform.user.domain.AppUser; -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; - -@Path("/additionalfields") -@Component -@Scope("singleton") -public class AdditionalFieldsApiResource { - - private final static Logger logger = LoggerFactory - .getLogger(AdditionalFieldsApiResource.class); - - private final PlatformSecurityContext context; - - @Autowired - public AdditionalFieldsApiResource(final PlatformSecurityContext context) { - this.context = context; - } - - @Autowired - private AdditionalFieldsService readWriteAdditionalFieldsService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - @GET - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String datasets(@QueryParam("type") final String type, - @Context final UriInfo uriInfo) { - - List result = this.readWriteAdditionalFieldsService - .retrieveExtraDatasetNames(type); - - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo - .getQueryParameters()); - return this.apiJsonSerializerService - .serializeAdditionalFieldsSetDataToJson(prettyPrint, result); - } - - @GET - @Path("{type}/{set}/{id}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String extraData(@PathParam("type") final String type, - @PathParam("set") final String set, @PathParam("id") final Long id, - @Context final UriInfo uriInfo) { - - checkUserPermissionForSet(type, set, "READ"); - - try { - GenericResultsetData result = this.readWriteAdditionalFieldsService - .retrieveExtraData(type, set, id); - - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo - .getQueryParameters()); - return this.apiJsonSerializerService - .serializeGenericResultsetDataToJson(prettyPrint, result); - } catch (InvalidSqlException e) { - List dataValidationErrors = new ArrayList(); - ApiParameterError error = ApiParameterError.parameterError( - "extradata.invalid.sql", "The sql is invalid.", "sql", - e.getSql()); - dataValidationErrors.add(error); - throw new PlatformApiDataValidationException( - "validation.msg.validation.errors.exist", - "Validation errors exist.", dataValidationErrors); - } - } - - @POST - @Path("{type}/{set}/{id}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response saveExtraData(@PathParam("type") final String type, - @PathParam("set") final String set, @PathParam("id") final Long id, - final String jsonRequestBody) { - - checkUserPermissionForSet(type, set, "UPDATE"); - - try { - - Map queryParams = new HashMap(); - String pValue = ""; - String pName; - try { - JSONObject jsonObj = new JSONObject(jsonRequestBody); - JSONArray jsonArr = jsonObj.names(); - if (jsonArr != null) { - for (int i = 0; i < jsonArr.length(); i++) { - pName = (String) jsonArr.get(i); - pValue = jsonObj.getString(pName); - logger.info(pName + " - " + pValue); - queryParams.put(pName, pValue); - } - } else { - throw new WebApplicationException(Response - .status(Status.BAD_REQUEST) - .entity("JSON body empty").build()); - } - } catch (JSONException e) { - throw new WebApplicationException(Response - .status(Status.BAD_REQUEST) - .entity("JSON body is wrong").build()); - } - - this.readWriteAdditionalFieldsService.updateExtraData(type, set, - id, queryParams); - - EntityIdentifier entityIdentifier = new EntityIdentifier( - Long.valueOf(id)); - - return Response.ok().entity(entityIdentifier).build(); - } catch (InvalidSqlException e) { - - List dataValidationErrors = new ArrayList(); - ApiParameterError error = ApiParameterError.parameterError( - "extradata.invalid.sql", "The sql is invalid.", "sql", - e.getSql()); - dataValidationErrors.add(error); - throw new PlatformApiDataValidationException( - "validation.msg.validation.errors.exist", - "Validation errors exist.", dataValidationErrors); - } - } - - private void checkUserPermissionForSet(String type, String set, - String accessType) { - AppUser currentUser = context.authenticatedUser(); - if (currentUser.hasNotPermissionForSet(type, set, accessType)) { - throw new NoAuthorizationException("Not Authorised to Use Set: " - + set + " of Type: " + type); - } - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/AdditionalFieldsSetData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/AdditionalFieldsSetData.java deleted file mode 100644 index 2da80448d..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/AdditionalFieldsSetData.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.mifosng.platform.api.data; - -/** - * Immutable data object for 'additional data'. - */ -public class AdditionalFieldsSetData { - - private final Integer id; - private final String name; - private final String type; - - public AdditionalFieldsSetData(final Integer id, final String name, final String type) { - this.id = id; - this.name = name; - this.type = type; - } - - public Integer getId() { - return id; - } - - public String getName() { - return name; - } - - public String getType() { - return type; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ResultsetColumnHeader.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ResultsetColumnHeader.java index 9409b5c06..c1b5be86b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ResultsetColumnHeader.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ResultsetColumnHeader.java @@ -10,29 +10,15 @@ public class ResultsetColumnHeader { private String columnName; private String columnType; private Long columnLength; - private String columnDisplayTypeNew; - // TODO - remove columnDisplayType when Additional Fields functionality - // removed and rename columnDisplayTypeNew to columnDisplayType private String columnDisplayType; private boolean isColumnNullable; private boolean isColumnPrimaryKey; - private List columnValuesNew = new ArrayList(); - // TODO - remove columnValues when Additional Fields functionality removed - // and rename columnValuesNew to columnValues - private List columnValues = new ArrayList(); + private List columnValues = new ArrayList(); public ResultsetColumnHeader() { } - public List getColumnValues() { - return columnValues; - } - - public void setColumnValues(List columnValues) { - this.columnValues = columnValues; - } - public String getColumnName() { return columnName; } @@ -57,20 +43,12 @@ public class ResultsetColumnHeader { this.columnLength = columnLength; } - public String getColumnDisplayType() { - return columnDisplayType; + public List getColumnValues() { + return columnValues; } - public void setColumnDisplayType(String columnDisplayType) { - this.columnDisplayType = columnDisplayType; - } - - public List getColumnValuesNew() { - return columnValuesNew; - } - - public void setColumnValuesNew(List columnValuesNew) { - this.columnValuesNew = columnValuesNew; + public void setColumnValues(List columnValues) { + this.columnValues = columnValues; } public boolean isColumnNullable() { @@ -89,20 +67,20 @@ public class ResultsetColumnHeader { this.isColumnPrimaryKey = isColumnPrimaryKey; } - public String getColumnDisplayTypeNew() { - return columnDisplayTypeNew; + public String getColumnDisplayType() { + return columnDisplayType; } - public void setColumnDisplayTypeNew() { + public void setColumnDisplayType() { - if (this.getColumnValuesNew().size() > 0) { + if (this.getColumnValues().size() > 0) { if (this.getColumnType().equalsIgnoreCase("int")) { - this.columnDisplayTypeNew = "CODELOOKUP"; + this.columnDisplayType = "CODELOOKUP"; return; } if (this.getColumnType().equalsIgnoreCase("varchar")) { - this.columnDisplayTypeNew = "CODEVALUE"; + this.columnDisplayType = "CODEVALUE"; return; } @@ -113,7 +91,7 @@ public class ResultsetColumnHeader { } if (this.getColumnType().equalsIgnoreCase("varchar") || this.getColumnType().equalsIgnoreCase("char")) { - this.columnDisplayTypeNew = "STRING"; + this.columnDisplayType = "STRING"; return; } @@ -122,17 +100,17 @@ public class ResultsetColumnHeader { || this.getColumnType().equalsIgnoreCase("smallint") || this.getColumnType().equalsIgnoreCase("mediumint") || this.getColumnType().equalsIgnoreCase("tinyint")) { - this.columnDisplayTypeNew = "INTEGER"; + this.columnDisplayType = "INTEGER"; return; } if (this.getColumnType().equalsIgnoreCase("date")) { - this.columnDisplayTypeNew = "DATE"; + this.columnDisplayType = "DATE"; return; } if (this.getColumnType().equalsIgnoreCase("decimal")) { - this.columnDisplayTypeNew = "DECIMAL"; + this.columnDisplayType = "DECIMAL"; return; } @@ -140,7 +118,7 @@ public class ResultsetColumnHeader { || this.getColumnType().equalsIgnoreCase("mediumtext") || this.getColumnType().equalsIgnoreCase("longtext") || this.getColumnType().equalsIgnoreCase("tinytext")) { - this.columnDisplayTypeNew = "TEXT"; + this.columnDisplayType = "TEXT"; return; } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/GoogleGsonPortfolioApiJsonSerializerService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/GoogleGsonPortfolioApiJsonSerializerService.java index 71e41b8f1..de0d7e317 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/GoogleGsonPortfolioApiJsonSerializerService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/GoogleGsonPortfolioApiJsonSerializerService.java @@ -7,7 +7,6 @@ import java.util.Set; import org.mifosng.platform.accounting.api.data.ChartOfAccountsData; import org.mifosng.platform.api.commands.ClientCommand; -import org.mifosng.platform.api.data.AdditionalFieldsSetData; import org.mifosng.platform.api.data.AppUserData; import org.mifosng.platform.api.data.AuthenticatedUserData; import org.mifosng.platform.api.data.ChargeData; @@ -196,12 +195,6 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi return helper.serializedJsonFrom(gsonDeserializer, resultsetData); } - @Override - public String serializeAdditionalFieldsSetDataToJson(final boolean prettyPrint, final Collection datasets) { - final Gson gsonDeserializer = helper.createGsonBuilder(prettyPrint); - return helper.serializedJsonFrom(gsonDeserializer, datasets.toArray(new AdditionalFieldsSetData[datasets.size()])); - } - @Override public String serializeDatatableDataToJson(final boolean prettyPrint, final Collection datatables) { final Gson gsonDeserializer = helper.createGsonBuilder(prettyPrint); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiJsonSerializerService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiJsonSerializerService.java index f51a20307..0900c8f43 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiJsonSerializerService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiJsonSerializerService.java @@ -5,7 +5,6 @@ import java.util.Set; import org.mifosng.platform.accounting.api.data.ChartOfAccountsData; import org.mifosng.platform.api.commands.ClientCommand; -import org.mifosng.platform.api.data.AdditionalFieldsSetData; import org.mifosng.platform.api.data.AppUserData; import org.mifosng.platform.api.data.AuthenticatedUserData; import org.mifosng.platform.api.data.ChargeData; @@ -47,8 +46,6 @@ public interface PortfolioApiJsonSerializerService { String serializeGenericResultsetDataToJson(boolean prettyPrint, GenericResultsetData result); - String serializeAdditionalFieldsSetDataToJson(boolean prettyPrint, Collection result); - String serializeDatatableDataToJson(boolean prettyPrint, Collection result); String serializePermissionDataToJson(boolean prettyPrint, Set responseParameters, Collection permissions); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/AdditionalFieldsNotFoundException.java b/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/AdditionalFieldsNotFoundException.java deleted file mode 100644 index 056277f04..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/AdditionalFieldsNotFoundException.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.mifosng.platform.exceptions; - -/** - * A {@link RuntimeException} thrown when client resources are not found. - */ -public class AdditionalFieldsNotFoundException extends AbstractPlatformResourceNotFoundException { - - public AdditionalFieldsNotFoundException(final String type, final Long id) { - super("error.msg.type.value.not.found", "Additional Fields Type: " - + type + " Id: " + id + " is not accessible"); - } - - public AdditionalFieldsNotFoundException(final String type, final String set) { - super("error.msg.set.not.found", "Additional Fields Set Not Found", - "Type: " + type + " Set: " + set); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/AdditionalFieldsService.java b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/AdditionalFieldsService.java deleted file mode 100644 index 3af867baf..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/AdditionalFieldsService.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.mifosng.platform.noncore; - -import java.util.List; -import java.util.Map; - -import org.mifosng.platform.api.data.AdditionalFieldsSetData; -import org.mifosng.platform.api.data.GenericResultsetData; - -public interface AdditionalFieldsService { - - // TODO - this service is deprecated and will be replaced by the data tables - // functionality - List retrieveExtraDatasetNames(String type); - - GenericResultsetData retrieveExtraData(String type, String set, Long id); - - void updateExtraData(String type, String set, Long id, - Map queryParams); - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/AdditionalFieldsServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/AdditionalFieldsServiceImpl.java deleted file mode 100644 index 83c4f380c..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/AdditionalFieldsServiceImpl.java +++ /dev/null @@ -1,480 +0,0 @@ -package org.mifosng.platform.noncore; - -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.sql.rowset.CachedRowSet; - -import org.apache.commons.lang.StringUtils; -import org.mifosng.platform.api.data.AdditionalFieldsSetData; -import org.mifosng.platform.api.data.GenericResultsetData; -import org.mifosng.platform.api.data.ResultsetColumnHeader; -import org.mifosng.platform.api.data.ResultsetDataRow; -import org.mifosng.platform.exceptions.AdditionalFieldsNotFoundException; -import org.mifosng.platform.exceptions.DataTableNotFoundException; -import org.mifosng.platform.exceptions.PlatformDataIntegrityException; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.mifosng.platform.user.domain.AppUser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -//TODO - this service is deprecated and will be replaced by the data tables functionality -@Service -public class AdditionalFieldsServiceImpl implements AdditionalFieldsService { - - private final PlatformSecurityContext context; - - private final static Logger logger = LoggerFactory - .getLogger(AdditionalFieldsServiceImpl.class); - - @Autowired - public AdditionalFieldsServiceImpl(final PlatformSecurityContext context) { - this.context = context; - } - - @Autowired - private GenericDataService genericDataService; - - @Override - public List retrieveExtraDatasetNames(String type) { - - long startTime = System.currentTimeMillis(); - List additionalFieldsSets = new ArrayList(); - - String andClause; - if (type == null) { - andClause = ""; - } else { - andClause = " and t.`name` = '" + type + "'"; - } - // PERMITTED ADDITIONAL FIELDS datasets - String sql = "select d.id, d.`name` as 'set', t.`name` as 'type' " - + " from stretchydata_dataset d join stretchydata_datasettype t on t.id = d.datasettype_id " - + " where exists" - + " (select 'f'" - + " from m_appuser_role ur " - + " join m_role r on r.id = ur.role_id" - + " left join m_role_permission rp on rp.role_id = r.id" - + " left join m_permission p on p.id = rp.permission_id" - + " where ur.appuser_id = " - + context.authenticatedUser().getId() - + " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', t.`name`, '_x', d.`name`))) " - + andClause + " order by d.`name`"; - - sql = genericDataService.wrapSQL(sql); - String sqlErrorMsg = "Additional Fields Type: " + type + " sql: " - + sql; - CachedRowSet rs = genericDataService.getCachedResultSet(sql, - sqlErrorMsg); - - try { - while (rs.next()) { - additionalFieldsSets.add(new AdditionalFieldsSetData(rs - .getInt("id"), rs.getString("set"), rs - .getString("type"))); - } - - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage(), sqlErrorMsg); - } - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING retrieveExtraDatasetNames: Elapsed Time: " - + elapsed); - - return additionalFieldsSets; - } - - @Override - public GenericResultsetData retrieveExtraData(String type, String set, - Long id) { - - long startTime = System.currentTimeMillis(); - - checkMainResourceExistsWithinScope(type, id); - - CachedRowSet columnDefinitions = getAdditionalFieldsMetaData(type, set); - - String sqlErrorMsg = "Additional Fields Type: " + type + " Set: " - + set + " Id: " + id; - List columnHeaders = getResultsetColumnHeaders( - columnDefinitions, sqlErrorMsg); - - String selectFieldList = getSelectFieldListFromColumnHeaders(columnHeaders); - - String sql = "select " + selectFieldList + " from `" + type - + "` t left join `" + getFullDatasetName(type, set) - + "` s on s.id = t.id where t.id = " + id; - logger.info("addition fields sql: " + sql); - - List resultsetDataRows = getResultsetDataRows( - columnHeaders, sql, sqlErrorMsg); - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING SET: " + set + " Elapsed Time: " + elapsed); - - return new GenericResultsetData(columnHeaders, resultsetDataRows); - - } - - private String getSelectFieldListFromColumnHeaders( - List columnHeaders) { - - Boolean firstColumn = true; - String selectFieldList = ""; - String selectFieldSeparator = ""; - - for (ResultsetColumnHeader columnHeader : columnHeaders) { - if (firstColumn) { - selectFieldSeparator = " "; - firstColumn = false; - } else { - selectFieldSeparator = ", "; - } - selectFieldList += selectFieldSeparator + "s.`" - + columnHeader.getColumnName() + "`"; - } - return selectFieldList; - } - - private CachedRowSet getAdditionalFieldsMetaData(String type, String set) { - String sql = "select f.`name`, f.data_type, f.data_length, f.display_type, f.code_id " - + " from stretchydata_datasettype t " - + " join stretchydata_dataset d on d.datasettype_id = t.id " - + " join stretchydata_dataset_fields f on f.dataset_id = d.id " - + " where d.`name` = '" - + set - + "' and t.`name` = '" - + type - + "' order by f.id"; - - CachedRowSet columnDefinitions = genericDataService.getCachedResultSet( - sql, "SQL: " + sql); - - if (columnDefinitions.size() > 0) - return columnDefinitions; - - throw new AdditionalFieldsNotFoundException(type, set); - } - - private List getResultsetColumnHeaders( - CachedRowSet columnDefinitions, String sqlErrorMsg) { - - List columnHeaders = new ArrayList(); - ResultsetColumnHeader rschId = new ResultsetColumnHeader(); - rschId.setColumnName("id"); - rschId.setColumnType("Integer"); - columnHeaders.add(rschId); - - try { - - Integer codeId; - while (columnDefinitions.next()) { - ResultsetColumnHeader rsch = new ResultsetColumnHeader(); - rsch.setColumnName(columnDefinitions.getString("name")); - - rsch.setColumnType(columnDefinitions.getString("data_type")); - if (columnDefinitions.getInt("data_length") > 0) - rsch.setColumnLength(columnDefinitions - .getLong("data_length")); - - rsch.setColumnDisplayType(columnDefinitions - .getString("display_type")); - codeId = columnDefinitions.getInt("code_id"); - - if (codeId > 0) { - String sql = "select code_value from m_code_value where code_id = " - + codeId + " order by order_position, id"; - CachedRowSet rsValues = genericDataService - .getCachedResultSet(sql, "SQL: " + sql); - while (rsValues.next()) { - rsch.getColumnValues().add( - rsValues.getString("code_value")); - } - } - columnHeaders.add(rsch); - } - ; - return columnHeaders; - - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage(), sqlErrorMsg); - } - - } - - private List getResultsetDataRows( - List columnHeaders, String sql, - String sqlErrorMsg) { - - List resultsetDataRows = null; - CachedRowSet rs = genericDataService.getCachedResultSet(sql, - sqlErrorMsg); - - if (rs.size() != 1) - throw new PlatformDataIntegrityException("error.msg.sql.error", - "Expected One Entry to be Returned But " + rs.size() - + " were Found - " + sqlErrorMsg); - - String columnName = null; - String columnValue = null; - resultsetDataRows = new ArrayList(); - ResultsetDataRow resultsetDataRow; - - try { - while (rs.next()) { - resultsetDataRow = new ResultsetDataRow(); - List columnValues = new ArrayList(); - - for (int i = 0; i < columnHeaders.size(); i++) { - columnName = columnHeaders.get(i).getColumnName(); - columnValue = rs.getString(columnName); - columnValues.add(columnValue); - } - resultsetDataRow.setRow(columnValues); - resultsetDataRows.add(resultsetDataRow); - } - return resultsetDataRows; - - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage(), sqlErrorMsg); - } - - } - - @Override - public void updateExtraData(String type, String set, Long id, - Map queryParams) { - - long startTime = System.currentTimeMillis(); - - GenericResultsetData readResultset = retrieveExtraData(type, set, id); - - String idValue = readResultset.getData().get(0).getRow().get(0); - String transType = "E"; - if (idValue == null) - transType = "A"; - - String fullDatasetName = getFullDatasetName(type, set); - - String saveSql = getSaveSql(readResultset, fullDatasetName, id, - transType, queryParams); - - if (saveSql != null) { - String sqlErrorMsg = "Additional Fields Type: " + type + " Set: " - + set + " Id: " + id; - genericDataService.updateSQL(saveSql, sqlErrorMsg); - } - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING updateExtraData: Elapsed Time: " + elapsed - + " - type: " + type + " set: " + set + " id: " + id); - } - - private String getSaveSql(GenericResultsetData readResultset, - String fullSetName, Long id, String transType, - Map queryParams) { - - Set keys = queryParams.keySet(); - - String underscore = "_"; - String space = " "; - String pValue = null; - String keyUpdated = null; - List columnHeaders = readResultset - .getColumnHeaders(); - List columnValues = readResultset.getData().get(0).getRow(); - - Map updatedColumns = new HashMap(); - - for (String key : keys) { - if (!(key.equalsIgnoreCase("id"))) { - keyUpdated = genericDataService.replace(key, underscore, space); - pValue = queryParams.get(key); - - if (newValueValidAndChanged(keyUpdated, columnHeaders, - columnValues, pValue)) - updatedColumns.put(keyUpdated, pValue); - - } - } - - // just updating fields that have changed since pre-update read - though - // its possible these values are different from the page the user was - // looking at and even different from the current db values (if some - // other update got in quick) - would need a version field for - // completeness but its okay to take this risk with additional fields - // data - - if (updatedColumns.size() == 0) - return null; - - String pValueWrite = ""; - String saveSql = ""; - String singleQuote = "'"; - - if (transType.equals("E")) { - boolean firstColumn = true; - saveSql = "update `" + fullSetName + "` "; - - for (String key : updatedColumns.keySet()) { - if (firstColumn) { - saveSql += " set "; - firstColumn = false; - } else { - saveSql += ", "; - } - - pValue = updatedColumns.get(key); - if (StringUtils.isEmpty(pValue)) { - pValueWrite = "null"; - } else { - pValueWrite = singleQuote - + genericDataService.replace(pValue, singleQuote, - singleQuote + singleQuote) + singleQuote; - } - saveSql += "`" + key + "` = " + pValueWrite; - } - - saveSql += " where id = " + id; - } else { - String insertColumns = ""; - String selectColumns = ""; - String columnName = ""; - for (String key : updatedColumns.keySet()) { - pValue = updatedColumns.get(key); - - if (StringUtils.isEmpty(pValue)) { - pValueWrite = "null"; - } else { - pValueWrite = singleQuote - + genericDataService.replace(pValue, singleQuote, - singleQuote + singleQuote) + singleQuote; - } - columnName = "`" + key + "`"; - insertColumns += ", " + columnName; - selectColumns += "," + pValueWrite + " as " + columnName; - } - - saveSql = "insert into `" + fullSetName + "` (id" + insertColumns - + ")" + " select " + id + " as id" + selectColumns; - } - return saveSql; - } - - private boolean notTheSame(String currValue, String pValue) { - if (StringUtils.isEmpty(currValue) && StringUtils.isEmpty(pValue)) - return false; - - if (StringUtils.isEmpty(currValue)) - return true; - - if (StringUtils.isEmpty(pValue)) - return true; - - if (currValue.equals(pValue)) - return false; - - return true; - } - - private boolean newValueValidAndChanged(String key, - List columnHeaders, - List columnValues, String newValue) { - - String columnValue = null; - for (int i = 0; i < columnHeaders.size(); i++) { - if (columnHeaders.get(i).getColumnName().equalsIgnoreCase(key)) { - columnValue = columnValues.get(i); - - if ((!StringUtils.isEmpty(newValue)) - && columnHeaders.get(i).getColumnValues().size() > 0) { - if (!(columnHeaders.get(i).getColumnValues() - .contains(newValue))) { - throw new PlatformDataIntegrityException( - "error.msg.invalid.columnValue", - "Parameter Column Name: " + key + " - Value '" - + newValue - + "' not found in Allowed Value list"); - } - } - - if (notTheSame(columnValue, newValue)) { - logger.info("Difference - Column: " + key - + "- Current Value: " + columnValue - + " New Value: " + newValue); - return true; - - } - return false; - } - } - - throw new PlatformDataIntegrityException( - "error.msg.invalid.columnName", "Parameter Column Name: " + key - + " not found"); - } - - private String getFullDatasetName(final String type, final String set) { - return type + "_x" + set; - } - - // only exclusively datatable functions below here - private void checkMainResourceExistsWithinScope(String appTable, - Long appTableId) { - - String unscopedSql = "select t.id from " + appTable - + " t ${dataScopeCriteria} where t.id = " + appTableId; - - String sql = dataScopedSQL(unscopedSql, appTable); - - CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " - + sql); - - if (rs.size() == 0) - throw new DataTableNotFoundException(appTable, appTableId); - } - - private String dataScopedSQL(String unscopedSQL, String appTable) { - String dataScopeCriteria = null; - /* - * unfortunately have to, one way or another, be able to restrict data - * to the users office hierarchy. Here it's hardcoded for client and - * loan. They are the main application tables. But if additional fields - * are needed on other tables like group, loan_transaction or others the - * same applies (hardcoding of some sort) - */ - - AppUser currentUser = context.authenticatedUser(); - if (appTable.equalsIgnoreCase("m_client")) { - dataScopeCriteria = " join m_office o on o.id = t.office_id and o.hierarchy like '" - + currentUser.getOffice().getHierarchy() + "%'"; - } - if (appTable.equalsIgnoreCase("m_loan")) { - dataScopeCriteria = " join m_client c on c.id = t.client_id " - + " join m_office o on o.id = c.office_id and o.hierarchy like '" - + currentUser.getOffice().getHierarchy() + "%'"; - } - - if (dataScopeCriteria == null) { - throw new PlatformDataIntegrityException( - "error.msg.invalid.dataScopeCriteria", - "Application Table: " + appTable - + " not catered for in data Scoping"); - } - - return genericDataService.replace(unscopedSQL, "${dataScopeCriteria}", - dataScopeCriteria); - - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/GenericDataServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/GenericDataServiceImpl.java index 933f967a3..899388b25 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/GenericDataServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/GenericDataServiceImpl.java @@ -184,7 +184,7 @@ public class GenericDataServiceImpl implements GenericDataService { writer.append('\"' + columnHeaders.get(j).getColumnName() + '\"' + ": "); - currColType = columnHeaders.get(j).getColumnDisplayTypeNew(); + currColType = columnHeaders.get(j).getColumnDisplayType(); currVal = row.get(j); if (currVal != null) { if (currColType.equals("DECIMAL") diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataServiceImpl.java index cc9f2e68c..f01001840 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataServiceImpl.java @@ -538,7 +538,7 @@ public class ReadWriteNonCoreDataServiceImpl implements if (rsch.getColumnType().equalsIgnoreCase("int")) addCodesValueIfNecessary(rsch, "_cd"); - rsch.setColumnDisplayTypeNew(); + rsch.setColumnDisplayType(); columnHeaders.add(rsch); } @@ -568,7 +568,7 @@ public class ReadWriteNonCoreDataServiceImpl implements try { while (rsValues.next()) { - rsch.getColumnValuesNew().add( + rsch.getColumnValues().add( new ResultsetColumnValue(rsValues.getInt("id"), rsValues.getString("code_value"))); } @@ -788,11 +788,11 @@ public class ReadWriteNonCoreDataServiceImpl implements if (!StringUtils.isEmpty(paramValue)) { - if (columnHeader.getColumnValuesNew().size() > 0) { + if (columnHeader.getColumnValues().size() > 0) { // match code value or id List allowedValues = columnHeader - .getColumnValuesNew(); - if (columnHeader.getColumnDisplayTypeNew().equals("CODEVALUE")) { + .getColumnValues(); + if (columnHeader.getColumnDisplayType().equals("CODEVALUE")) { for (ResultsetColumnValue allowedValue : allowedValues) { if (paramValue .equalsIgnoreCase(allowedValue.getValue())) @@ -809,7 +809,7 @@ public class ReadWriteNonCoreDataServiceImpl implements "Validation errors exist.", dataValidationErrors); } - if (columnHeader.getColumnDisplayTypeNew().equals("CODELOOKUP")) { + if (columnHeader.getColumnDisplayType().equals("CODELOOKUP")) { for (ResultsetColumnValue allowedValue : allowedValues) { if (paramValue.equals(Integer.toString(allowedValue .getId()))) @@ -836,17 +836,17 @@ public class ReadWriteNonCoreDataServiceImpl implements JsonParserHelper helper = new JsonParserHelper(); - if (columnHeader.getColumnDisplayTypeNew().equals("DATE")) + if (columnHeader.getColumnDisplayType().equals("DATE")) paramValue = helper.convertFrom(paramValue, columnHeader.getColumnName(), dateFormat, clientApplicationLocale).toString(); - if (columnHeader.getColumnDisplayTypeNew().equals("INTEGER")) + if (columnHeader.getColumnDisplayType().equals("INTEGER")) paramValue = helper.convertToInteger(paramValue, columnHeader.getColumnName(), clientApplicationLocale) .toString(); - if (columnHeader.getColumnDisplayTypeNew().equals("DECIMAL")) + if (columnHeader.getColumnDisplayType().equals("DECIMAL")) paramValue = helper.convertFrom(paramValue, columnHeader.getColumnName(), clientApplicationLocale) .toString();
RESOURCES
POST
create/complex update
GET
read
PUT
update
DELETE
delete
ADDITIONAL FIELDSadditionalfields (deprecated)List Additional Fields Sets
additionalfields/{Type}/{Set}/{id} (deprecated)Update Additional FieldsRetrieve Additional Fields
DATA TABLEdatatablesList Data Tables
datatables/register/{datatable}/{apptable}Register Data Table
datatables/deregister/{datatable}Deregister Data Table
LOAN PRODUCTloanproductsCreate a Loan ProductList Loan Products
loanproducts/{productId}Retrieve a Loan ProductUpdate a Loan Product
CONFIGURATIONconfigurations/currencyRetrieve Currency ConfigurationUpdate Currency Configuration
ADDITIONAL FIELDSadditionalfields (deprecated)List Additional Fields Sets
additionalfields/{Type}/{Set}/{id} (deprecated)Update Additional FieldsRetrieve Additional Fields
DATA TABLEdatatablesList Data Tables
datatables/register/{datatable}/{apptable}Register Data Table
datatables/deregister/{datatable}Deregister Data Table