getLong replacement (temp) plus some api doc updates

This commit is contained in:
John Woodlock
2012-05-28 02:27:57 +10:00
parent 47749b2f45
commit cc8bd8ba5e
7 changed files with 150 additions and 95 deletions
+92 -74
View File
@@ -18,6 +18,8 @@
<div class="toc-section">
<ul>
<li><a href="#top">Mifos X API Documentation</a></li>
<li><a href="#interact">Try The API From Your Browser</a></li>
<li><a href="#genopts">Generic Options</a></li>
<li><a href="#authentication_overview">Authentication Overview</a></li>
<li><a href="#errors">Errors</a></li>
<li><a href="#fullapi_matrix">Full API Matrix</a></li>
@@ -125,7 +127,7 @@
<a id="top" name="top" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h1>Mifos X API Documentation</h1>
<h3>Mifos X API Documentation</h3>
<p>
The Mifos X API is organized around
<a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a>.
@@ -141,6 +143,53 @@
</p>
</div>
</div>
<a id="interact" name="interact" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h3>Try The API From Your Browser</h3>
<p>GET (read) examples can be run directly from this documentation. If you want to check out the POST, PUT and DELETE (update) examples you will need to
install a REST plugin for your browser e.g. RESTClient for FireFox</p>
The REST plugins will allow you to
<ul>
<li class=normalli>Select the "Verb" (e.g. POST)</li>
<li class=normalli>Enter the resource name (e.g. https://localhost:8443/mifosng-provider/api/v1/offices)</li>
<li class=normalli>Add a header to indicate you are sending JSON data as part of the request body (e.g. Content-Type: application/json)</li>
<li class=normalli>Paste the example JSON into a Request Body</li>
<li class=normalli>Send the Request (and recieve a Response)</li>
</ul>
</div>
</div>
<a id="genopts" name="genopts" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h3>Generic Options</h3>
<h4>Convenience Templates</h4>
<p>There are a list of convenience resources (see Convenience menu option). These resources end with "/template" and can be useful when building maintenance user interface screens for client applications. The template data returned may consist of any or all of:
<ul>
<li class=normalli>Field Defaults</li>
<li class=normalli>Allowed Value Lists</li>
</ul>
</p>
<p>Also, many "Retrieve a" type resource (<a href="#clients_retrieve">Retrieve a Client</a> for example) allow the parameter option "template=true".
This appends any "Allowed Value Lists" which can be useful when building update functionality.</p>
<h4>Restrict Returned Fields</h4>
<p>Parameter "fields={fieldlist}" can be used on GET requests to restrict the fields returned.</p>
<p>Example Request: </p>
<a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/offices/1?pretty=true&fields=id,name,parentName">
https://localhost:8443/mifosng-provider/api/v1/offices/1?pretty=true&fields=id,name,parentName
</a>
<p></p>
<h4>Pretty JSON Formatting</h4>
<p>Parameter "pretty=true" can be used to display JSON from GET requests in an easily readable format. This parameter is used in this documentation so that GET requests are immediately viewable.</p>
<p>If you want easily readable JSON output for POSTs, PUTs and DELETEs it will available in the REST plugin you use e.g. RESTClient for FireFox</p>
</div>
</div>
<a id="authentication_overview" name="authentication_overview" class="old-syle-anchor">&nbsp;</a>
@@ -1822,6 +1871,7 @@ Request Body:
<h4>List Offices</h4>
<p>Example Requests: </p>
<a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/offices?pretty=true">https://localhost:8443/mifosng-provider/api/v1/offices?pretty=true</a>
<br><br>
<a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/offices?fields=id,name,openingDate&pretty=true">https://localhost:8443/mifosng-provider/api/v1/offices?fields=id,name,openingDate&pretty=true</a>
</div>
<div class="method-example">
@@ -1859,67 +1909,31 @@ Request Body:
<div class="method-section">
<div class="method-description">
<h4>Retrieve Office Details Template</h4>
<p>Returns a template that contains the office fields and allowed value lists. This is a convienence when building user intereface screens for client applications.
<p>This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of:
<ul>
<li class=normalli>Field Defaults</li>
<li class=normalli>Allowed Value Lists</li>
</ul>
</p>
<p>Example Request:
<a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/offices/template">
https://localhost:8443/mifosng-provider/api/v1/offices/template
<p>Example Request: </p>
<a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/offices/template?pretty=true">
https://localhost:8443/mifosng-provider/api/v1/offices/template?pretty=true
</a>
</p>
</div>
<div class="method-example">
<code class="method-declaration">GET https://thedomainname/api/v1/offices/template</code>
<code class="method-response">
{
"id": null,
"name": null,
"externalId": null,
"openingDate": "2012-05-21",
"hierarchy": null,
"parentName": null,
"parentId": null,
"allowedParents": [
{
"id": 1,
"name": "Demo MFI Head Office",
"externalId": "1",
"openingDate": "2009-01-01",
"hierarchy": ".",
"parentName": null,
"parentId": 0,
"allowedParents": []
},
{
"id": 2,
"name": "sub branch 1",
"externalId": "2",
"openingDate": "2012-01-02",
"hierarchy": ".2.",
"parentName": "Demo MFI Head Office",
"parentId": 1,
"allowedParents": []
},
{
"id": 3,
"name": "sub branch 2",
"externalId": "3",
"openingDate": "2012-03-01",
"hierarchy": ".3.",
"parentName": "Demo MFI Head Office",
"parentId": 1,
"allowedParents": []
},
{
"id": 4,
"name": "sub branch 3",
"externalId": null,
"openingDate": "2012-04-17",
"hierarchy": ".4.",
"parentName": "Demo MFI Head Office",
"parentId": 1,
"allowedParents": []
}
]
<code class="method-response">{
"openingDate" : [ 2012, 5, 28 ],
"allowedParents" : [ {
"id" : 1,
"name" : "Demo MFI Head Office"
}, {
"id" : 2,
"name" : "B1"
}, {
"id" : 3,
"name" : "B2"
} ]
}
</code>
</div>
@@ -1928,26 +1942,30 @@ Request Body:
<a id="offices_retrieve" name="offices_retrieve" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Retrieve Office</h4>
<p>Returns an office details if it exists.</p>
<p>Example Request:
<a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/offices/1">
https://localhost:8443/mifosng-provider/api/v1/offices/1
<h4>Retrieve an Office</h4>
<p>Example Requests: </p>
<a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/offices/1?pretty=true">
https://localhost:8443/mifosng-provider/api/v1/offices/1?pretty=true
</a>
<br><br>
<a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/offices/1?pretty=true&template=true">
https://localhost:8443/mifosng-provider/api/v1/offices/1?pretty=true&template=true
</a>
<br><br>
<a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/offices/1?pretty=true&fields=id,name,parentName">
https://localhost:8443/mifosng-provider/api/v1/offices/1?pretty=true&fields=id,name,parentName
</a>
</p>
</div>
<div class="method-example">
<code class="method-declaration">GET https://thedomainname/api/v1/offices/1</code>
<code class="method-response">
{
"id": 1,
"name": "Demo MFI Head Office",
"externalId": "1",
"openingDate": "2009-01-01",
"hierarchy": ".",
"parentName": null,
"parentId": 0,
"allowedParents": []
<code class="method-response">{
"id" : 1,
"name" : "Demo MFI Head Office",
"externalId" : "1",
"openingDate" : [ 2009, 1, 1 ],
"hierarchy" : ".",
"parentName" : null,
"parentId" : null
}
</code>
</div>
@@ -2431,7 +2449,7 @@ Request Body:
<p>Returns the list of currencies permitted for use AND the list of currencies not selected (but available for selection).</p>
<p>Example Requests: </p>
<a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/configurations/currency?pretty=true">https://localhost:8443/mifosng-provider/api/v1/configurations/currency?pretty=true</a>
<br>
<br><br>
<a style="word-wrap: break-word;" href="https://localhost:8443/mifosng-provider/api/v1/configurations/currency?pretty=true&fields=selectedCurrencyOptions">https://localhost:8443/mifosng-provider/api/v1/configurations/currency?pretty=true&fields=selectedCurrencyOptions</a>
</div>
<div class="method-example">
+1
View File
@@ -43,6 +43,7 @@
color: rgb(240, 240, 255);
}
.normalli {list-style:disc outside none;}
html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,tdjpw{margin:0;padding:0;}tablejpw{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}
+1 -1
View File
@@ -1,6 +1,6 @@
\loan\?\transactions\id get exception if loan doesn't match id.... should loan be taken out here?
template for waiver/repayment... is it same for both? no type needed?
new loan template ... is it 2 templates... one to pick product... and 2nd to return default properties in selected product
new loan template ... is it 2 templates... one to pick product... and 2nd to return default properties in selected product or is it meant that if only one product then use that.
Configuration
@@ -434,6 +434,8 @@ public class ReadExtraDataAndReportingServiceImpl implements
rsch.setColumnDisplayType(rsmd.getString("display_type"));
allowedListId = rsmd.getInt("allowed_list_id");
if (allowedListId != null) {
logger.info("allowedListId != null: Column: " + rsch.getColumnName());
sql = "select v.`name` from stretchydata_allowed_value v where allowed_list_id = "
+ allowedListId + " order by id";
ResultSet rsValues = db_statement2.executeQuery(sql);
@@ -7,8 +7,10 @@ import org.joda.time.LocalDate;
public interface ApiDataConversionService {
LocalDate convertFrom(String dateAsString, String parameterName, String dateFormat);
LocalDate convertFrom(String dateAsString, String parameterName,
String dateFormat);
BigDecimal convertFrom(String principalFormatted, String parameterName, Locale clientApplicationLocale);
BigDecimal convertFrom(String principalFormatted, String parameterName,
Locale clientApplicationLocale);
}
@@ -19,45 +19,69 @@ import org.springframework.stereotype.Service;
public class ApiDataConversionServiceImpl implements ApiDataConversionService {
@Override
public LocalDate convertFrom(String dateAsString, String parameterName, String dateFormat) {
public LocalDate convertFrom(String dateAsString, String parameterName,
String dateFormat) {
LocalDate eventLocalDate = null;
if (StringUtils.isNotBlank(dateAsString)) {
try {
Locale locale = LocaleContextHolder.getLocale();
eventLocalDate = DateTimeFormat.forPattern(dateFormat).withLocale(locale).parseLocalDate(dateAsString.toLowerCase(locale));
eventLocalDate = DateTimeFormat.forPattern(dateFormat)
.withLocale(locale)
.parseLocalDate(dateAsString.toLowerCase(locale));
} catch (IllegalArgumentException e) {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
ApiParameterError error = ApiParameterError.parameterError("validation.msg.invalid.date.format", "The parameter " + parameterName + " is invalid based on the dateFormat provided:" + dateFormat, parameterName, dateAsString, dateFormat);
ApiParameterError error = ApiParameterError
.parameterError(
"validation.msg.invalid.date.format",
"The parameter "
+ parameterName
+ " is invalid based on the dateFormat provided:"
+ dateFormat, parameterName,
dateAsString, dateFormat);
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
throw new PlatformApiDataValidationException(
"validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors);
}
}
return eventLocalDate;
}
@Override
public BigDecimal convertFrom(String numericalValueFormatted, String parameterName, Locale clientApplicationLocale) {
public BigDecimal convertFrom(String numericalValueFormatted,
String parameterName, Locale clientApplicationLocale) {
try {
BigDecimal number = null;
if (StringUtils.isNotBlank(numericalValueFormatted)) {
String sourceWithoutSpaces = numericalValueFormatted.replaceAll(" ", "");
NumberFormat format = NumberFormat.getNumberInstance(clientApplicationLocale);
String sourceWithoutSpaces = numericalValueFormatted
.replaceAll(" ", "");
NumberFormat format = NumberFormat
.getNumberInstance(clientApplicationLocale);
Number parsedNumber = format.parse(sourceWithoutSpaces);
number = BigDecimal.valueOf(Double.valueOf(parsedNumber.doubleValue()));
number = BigDecimal.valueOf(Double.valueOf(parsedNumber
.doubleValue()));
}
return number;
} catch (ParseException e) {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
ApiParameterError error = ApiParameterError.parameterError("validation.msg.invalid.number.format", "The parameter " + parameterName + " is invalid for provided locale" + clientApplicationLocale.toString() + ".", parameterName, numericalValueFormatted, clientApplicationLocale);
ApiParameterError error = ApiParameterError.parameterError(
"validation.msg.invalid.number.format", "The parameter "
+ parameterName + " is invalid for provided locale"
+ clientApplicationLocale.toString() + ".",
parameterName, numericalValueFormatted,
clientApplicationLocale);
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
throw new PlatformApiDataValidationException(
"validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors);
}
}
}
@@ -32,7 +32,7 @@ public class OfficeReadPlatformServiceImpl implements OfficeReadPlatformService
this.context = context;
this.jdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
private static final class OfficeMapper implements RowMapper<OfficeData> {
public String officeSchema() {
@@ -49,7 +49,9 @@ public class OfficeReadPlatformServiceImpl implements OfficeReadPlatformService
String externalId = rs.getString("externalId");
LocalDate openingDate = new LocalDate(rs.getDate("openingDate"));
String hierarchy = rs.getString("hierarchy");
Long parentId = rs.getLong("parentId");
Long parentId = getRSLong(rs.getString("parentId"), rs.getLong("parentId"));
String parentName = rs.getString("parentName");
return new OfficeData(id, name, externalId, openingDate, hierarchy,
@@ -165,4 +167,10 @@ public class OfficeReadPlatformServiceImpl implements OfficeReadPlatformService
}
public static Long getRSLong(String stringVal, Long longVal) {
if (stringVal == null)
return null;
return longVal;
}
}