wip update data tables and docs
This commit is contained in:
@@ -2386,7 +2386,180 @@ Request Body:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- start of datatables api docs -->
|
||||
<a id="additionalfields" name="additionalfields" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h3>Additional Fields (Deprecated)</h3>
|
||||
<p>
|
||||
In Mifos X, any number of "Sets" of "Additional Fields" can be configured for a Mifos X database table ("Type").
|
||||
</p>
|
||||
<p> 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.
|
||||
</p>
|
||||
<p>
|
||||
The additional fields resource allows you to retrieve and update any Additional Fields data that has been configured in Mifos X.
|
||||
</p>
|
||||
<p>
|
||||
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).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<a id="additionalfields_list" name="additionalfields_list" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>List Additional Fields Sets</h4>
|
||||
<p>
|
||||
Lists the Sets of additional fields have been defined in Mifos X.
|
||||
</p>
|
||||
|
||||
<h5>Arguments</h5>
|
||||
<dl class="argument-list">
|
||||
<dt>type</dt>
|
||||
<dd><span>optional</span></dd>
|
||||
<dd>The Additional Fields Type (Mifos X database table) to restrict the output to</dd>
|
||||
</dl>
|
||||
<p>Example Requests: </p>
|
||||
<div class=apiClick>additionalfields?type=m_client</div>
|
||||
<br><br>
|
||||
<div class=apiClick>additionalfields</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/additionalfields</code>
|
||||
<code class="method-response">[ {
|
||||
"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"
|
||||
} ]
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<a id="additionalfields_retrieve" name="additionalfields_retrieve" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Retrieve Additional Fields</h4>
|
||||
<p>
|
||||
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).
|
||||
</p>
|
||||
<p>Example Request:
|
||||
<div class=apiClick>additionalfields/m_client/Additional Information/2</div>
|
||||
</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/additionalfields/{type}/{set}/{id}</code>
|
||||
<code class="method-response">{
|
||||
"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" ]
|
||||
} ]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<a id="additionalfields_update" name="additionalfields_update" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Update Additional Fields</h4>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/additionalfields/{type}/{set}/{id}</code>
|
||||
<code class="method-request">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"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"entityId": 2
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- start of reports api docs -->
|
||||
<a id="reports" name="reports" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.mifosng.platform.api.data.GenericResultsetData;
|
||||
import org.mifosng.platform.api.infrastructure.ApiJsonSerializerService;
|
||||
import org.mifosng.platform.api.infrastructure.ApiParameterHelper;
|
||||
import org.mifosng.platform.exceptions.NoAuthorizationException;
|
||||
import org.mifosng.platform.noncore.GenericDataService;
|
||||
import org.mifosng.platform.noncore.ReadWriteNonCoreDataService;
|
||||
import org.mifosng.platform.security.PlatformSecurityContext;
|
||||
import org.mifosng.platform.user.domain.AppUser;
|
||||
@@ -53,6 +54,9 @@ public class DataTableApiResource {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private GenericDataService genericDataService;
|
||||
|
||||
@Autowired
|
||||
private ReadWriteNonCoreDataService readWriteNonCoreDataService;
|
||||
|
||||
@@ -113,21 +117,23 @@ public class DataTableApiResource {
|
||||
|
||||
checkUserPermissionForDatatable(datatable, "READ");
|
||||
|
||||
/*
|
||||
* Dont use this for now... but its the code for returning data as json
|
||||
* objects rather than a generic resultset String resultStr =
|
||||
* this.readWriteNonCoreDataService
|
||||
* .retrieveDataTableJSONObject(datatable, id, sqlFields, sqlOrder);
|
||||
*/
|
||||
|
||||
GenericResultsetData results = this.readWriteNonCoreDataService
|
||||
.retrieveDataTableGenericResultSet(datatable, apptableId,
|
||||
sqlFields, sqlOrder, null);
|
||||
|
||||
boolean prettyPrints = ApiParameterHelper.prettyPrint(uriInfo
|
||||
boolean genericResultSet = ApiParameterHelper.genericResultSet(uriInfo
|
||||
.getQueryParameters());
|
||||
return this.apiJsonSerializerService
|
||||
.serializeGenericResultsetDataToJson(prettyPrints, results);
|
||||
|
||||
if (genericResultSet) {
|
||||
boolean prettyPrints = ApiParameterHelper.prettyPrint(uriInfo
|
||||
.getQueryParameters());
|
||||
return this.apiJsonSerializerService
|
||||
.serializeGenericResultsetDataToJson(prettyPrints, results);
|
||||
} else {
|
||||
|
||||
return this.genericDataService
|
||||
.generateJsonFromGenericResultsetData(results);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -60,7 +60,7 @@ public class ApiParameterHelper {
|
||||
}
|
||||
return parameterType;
|
||||
}
|
||||
|
||||
|
||||
public static boolean template(final MultivaluedMap<String, String> queryParams) {
|
||||
boolean template = false;
|
||||
if (queryParams.getFirst("template") != null) {
|
||||
@@ -69,4 +69,13 @@ public class ApiParameterHelper {
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
public static boolean genericResultSet(final MultivaluedMap<String, String> queryParams) {
|
||||
boolean genericResultSet = false;
|
||||
if (queryParams.getFirst("genericResultSet") != null) {
|
||||
String genericResultSetValue = queryParams.getFirst("genericResultSet");
|
||||
genericResultSet = "true".equalsIgnoreCase(genericResultSetValue);
|
||||
}
|
||||
return genericResultSet;
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,8 @@ public interface GenericDataService {
|
||||
|
||||
GenericResultsetData fillGenericResultSet(final String sql);
|
||||
|
||||
String generateJsonFromGenericResultsetData(GenericResultsetData grs);
|
||||
|
||||
String replace(String str, String pattern, String replace);
|
||||
|
||||
String wrapSQL(String sql);
|
||||
|
||||
+59
-1
@@ -11,6 +11,7 @@ import java.util.List;
|
||||
import javax.sql.DataSource;
|
||||
import javax.sql.rowset.CachedRowSet;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.platform.api.data.GenericResultsetData;
|
||||
import org.mifosng.platform.api.data.ResultsetColumnHeader;
|
||||
import org.mifosng.platform.api.data.ResultsetDataRow;
|
||||
@@ -22,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.sun.rowset.CachedRowSetImpl;
|
||||
|
||||
//TODO - Performance Item - most items (code values etc) can be cached but not doing that yet
|
||||
@Service
|
||||
public class GenericDataServiceImpl implements GenericDataService {
|
||||
|
||||
@@ -39,6 +40,7 @@ public class GenericDataServiceImpl implements GenericDataService {
|
||||
|
||||
@Override
|
||||
public CachedRowSet getCachedResultSet(String sql, String sqlErrorMsg) {
|
||||
//TODO - Need to reimplement this away from Sun library - could be mixture of Lists and jdbcTemplate.query
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
Connection db_connection = null;
|
||||
@@ -157,6 +159,62 @@ public class GenericDataServiceImpl implements GenericDataService {
|
||||
return "select x.* from (" + sql + ") x";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateJsonFromGenericResultsetData(GenericResultsetData grs) {
|
||||
|
||||
StringBuffer writer = new StringBuffer();
|
||||
|
||||
writer.append("[");
|
||||
|
||||
List<ResultsetColumnHeader> columnHeaders = grs.getColumnHeaders();
|
||||
logger.info("NO. of Columns: " + columnHeaders.size());
|
||||
|
||||
List<ResultsetDataRow> data = grs.getData();
|
||||
List<String> row;
|
||||
Integer rSize;
|
||||
String currColType;
|
||||
String currVal;
|
||||
logger.info("NO. of Rows: " + data.size());
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
writer.append("\n{");
|
||||
|
||||
row = data.get(i).getRow();
|
||||
rSize = row.size();
|
||||
for (int j = 0; j < rSize; j++) {
|
||||
|
||||
writer.append('\"' + columnHeaders.get(j).getColumnName()
|
||||
+ '\"' + ": ");
|
||||
currColType = columnHeaders.get(j).getColumnDisplayTypeNew();
|
||||
currVal = row.get(j);
|
||||
if (currVal != null) {
|
||||
if (currColType.equals("DECIMAL")
|
||||
|| currColType.equals("INTEGER"))
|
||||
writer.append(currVal);
|
||||
else {
|
||||
if (currColType.equals("DATE")) {
|
||||
LocalDate localDate = new LocalDate(currVal);
|
||||
writer.append("[" + localDate.getYear() + ", " + localDate.getMonthOfYear() + ", " + localDate.getDayOfMonth() + "]");
|
||||
} else
|
||||
writer.append('\"' + currVal + '\"');
|
||||
}
|
||||
} else
|
||||
writer.append("null");
|
||||
|
||||
if (j < (rSize - 1))
|
||||
writer.append(",\n");
|
||||
}
|
||||
|
||||
if (i < (data.size() - 1))
|
||||
writer.append("},");
|
||||
else
|
||||
writer.append("}");
|
||||
}
|
||||
|
||||
writer.append("\n]");
|
||||
return writer.toString();
|
||||
|
||||
}
|
||||
|
||||
private void dbClose(Statement db_statement, Connection db_connection) {
|
||||
logger.debug("dbClose");
|
||||
try {
|
||||
|
||||
-3
@@ -20,9 +20,6 @@ public interface ReadWriteNonCoreDataService {
|
||||
GenericResultsetData retrieveDataTableGenericResultSet(String datatable,
|
||||
Long appTableId, String sqlFields, String sqlOrder, Long id);
|
||||
|
||||
String retrieveDataTableJSONObject(String datatable, Long appTableId,
|
||||
String sqlFields, String sqlOrder);
|
||||
|
||||
void newDatatableEntry(String datatable, Long appTableId,
|
||||
Map<String, String> queryParams);
|
||||
|
||||
|
||||
-67
@@ -294,22 +294,6 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String retrieveDataTableJSONObject(String datatable,
|
||||
Long appTableId, String sqlFields, String sqlOrder) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
GenericResultsetData result = retrieveDataTableGenericResultSet(
|
||||
datatable, appTableId, sqlFields, sqlOrder, null);
|
||||
|
||||
String jsonString = generateJsonFromGenericResultsetData(result);
|
||||
|
||||
long elapsed = System.currentTimeMillis() - startTime;
|
||||
logger.info("FINISHING DATATABLE JSON OBJECT: " + datatable
|
||||
+ " Elapsed Time: " + elapsed);
|
||||
return jsonString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericResultsetData retrieveDataTableGenericResultSet(
|
||||
String datatable, Long appTableId, String sqlFields,
|
||||
@@ -595,57 +579,6 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
|
||||
}
|
||||
|
||||
private static String generateJsonFromGenericResultsetData(
|
||||
GenericResultsetData result) {
|
||||
|
||||
StringBuffer writer = new StringBuffer();
|
||||
|
||||
writer.append("[");
|
||||
|
||||
List<ResultsetColumnHeader> columnHeaders = result.getColumnHeaders();
|
||||
logger.info("NO. of Columns: " + columnHeaders.size());
|
||||
|
||||
List<ResultsetDataRow> data = result.getData();
|
||||
List<String> row;
|
||||
Integer rSize;
|
||||
String currColType;
|
||||
String currVal;
|
||||
logger.info("NO. of Rows: " + data.size());
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
writer.append("\n{");
|
||||
|
||||
row = data.get(i).getRow();
|
||||
rSize = row.size();
|
||||
for (int j = 0; j < rSize; j++) {
|
||||
|
||||
writer.append('\"' + columnHeaders.get(j).getColumnName()
|
||||
+ '\"' + ": ");
|
||||
currColType = columnHeaders.get(j).getColumnDisplayTypeNew();
|
||||
currVal = row.get(j);
|
||||
if (currVal != null) {
|
||||
if (currColType.equals("DECIMAL")
|
||||
|| currColType.equals("INTEGER"))
|
||||
writer.append(currVal);
|
||||
else
|
||||
writer.append('\"' + currVal + '\"');
|
||||
} else
|
||||
writer.append("null");
|
||||
|
||||
if (j < (rSize - 1))
|
||||
writer.append(",\n");
|
||||
}
|
||||
|
||||
if (i < (data.size() - 1))
|
||||
writer.append("},");
|
||||
else
|
||||
writer.append("}");
|
||||
}
|
||||
|
||||
writer.append("\n]");
|
||||
return writer.toString();
|
||||
|
||||
}
|
||||
|
||||
private String getAddSql(List<ResultsetColumnHeader> columnHeaders,
|
||||
String datatable, String fkName, Long appTableId,
|
||||
Map<String, String> queryParams) {
|
||||
|
||||
Reference in New Issue
Block a user