update staff api docs and validation.

This commit is contained in:
Keith Woodlock
2013-01-28 13:21:36 +00:00
parent 17f6e6ba66
commit 0bc06f9215
5 changed files with 211 additions and 81 deletions
+139
View File
@@ -246,6 +246,21 @@ function getBaseURL(docURL)
<td><a href="#fund_update">Update a Fund</a></td>
<td></td>
</tr>
<tr class="alt">
<td><a href="#staff">STAFF</a></td><td>staff</td>
<td><a href="#staff_create">Create a Staff</a></td>
<td><a href="#staff_list">List Staff</a></td>
<td></td>
<td></td>
</tr>
<tr class="alt">
<td></td>
<td>staff/{staffId}</td>
<td></td>
<td><a href="#staff_retrieve">Retrieve a Staff Member</a></td>
<td><a href="#staff_update">Update a Staff Member</a></td>
<td></td>
</tr>
</table>
</div>
</div>
@@ -2579,6 +2594,115 @@ Request Body:
</div>
</div>
<a id="staff" name="staff" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h3>Staff</h3>
<p>Allows you to model staff members. At present the key role of signifigance is whether this staff member is a loan officer or not.</p>
</div>
</div>
<a id="staff_create" name="staff_create" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Create a staff member</h4>
<p>Creates a staff member.</p>
</div>
<div class="method-example">
<code class="method-declaration">POST https://Domain Name/api/v1/staff</code>
<code class="method-request">POST staff
Content-Type: application/json
Request Body:
{
"officeId": 1,
"firstname": "John",
"lastname": "Doe",
"isLoanOfficer": "true"
}
</code>
<code class="method-response">{
"officeId": 1,
"resourceId": 1
}
</code>
</div>
</div>
<a id="staff_list" name="staff_list" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Retrieve Staff</h4>
<p>Returns the list of staff members.</p>
<p>Example Requests: </p>
<div class=apiClick>staff</div>
</div>
<div class="method-example">
<code class="method-declaration">GET https://Domain Name/api/v1/staff</code>
<code class="method-response">[
{
"id": 1,
"firstname": "John",
"lastname": "Doe",
"displayName": "Doe, John",
"officeId": 1,
"officeName": "Head Office",
"isLoanOfficer": true
}
]
</code>
</div>
</div>
<a id="staff_retrieve" name="staff_retrieve" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Retrieve a Staff Member</h4>
<p>Returns the details of a Staff Member.</p>
<p>Example Requests: </p>
<div class=apiClick>staff/1</div>
</div>
<div class="method-example">
<code class="method-declaration">GET https://Domain Name/api/v1/staff/1</code>
<code class="method-response">{
"id": 1,
"firstname": "John",
"lastname": "Doe",
"displayName": "Doe, John",
"officeId": 1,
"officeName": "Head Office",
"isLoanOfficer": true
}
</code>
</div>
</div>
<a id="staff_update" name="staff_update" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Update a Staff Member</h4>
<p>Updates the details of a staff member.</p>
</div>
<div class="method-example">
<code class="method-declaration">PUT https://Domain Name/api/v1/staff/1</code>
<code class="method-request">PUT staff/1
Content-Type: application/json
Request Body:
{
"isLoanOfficer": "false"
}
</code>
<code class="method-response">{
"officeId": 1,
"resourceId": 1,
"changes": {
"isLoanOfficer": false
}
}
</code>
</div>
</div>
<!-- start of datatables api docs -->
<a id="datatables" name="datatables" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
@@ -3700,6 +3824,21 @@ Request body:
<td><a href="#fund_update">Update a Fund</a></td>
<td></td>
</tr>
<tr class="alt">
<td><a href="#staff">STAFF</a></td><td>staff</td>
<td><a href="#staff_create">Create a Staff</a></td>
<td><a href="#staff_list">List Staff</a></td>
<td></td>
<td></td>
</tr>
<tr class="alt">
<td></td>
<td>staff/{staffId}</td>
<td></td>
<td><a href="#staff_retrieve">Retrieve a Staff Member</a></td>
<td><a href="#staff_update">Update a Staff Member</a></td>
<td></td>
</tr>
<tr><td><a href="#datatables">DATA TABLE</a></td><td>datatables</td><td></td><td><a href="#datatables_list">List Data Tables</a></td><td></td><td></td></tr>
<tr class="alt"><td></td><td>datatables/register/{datatable}/{apptable}</td><td><a href="#datatables_register">Register Data Table</a></td><td></td><td></td><td></td></tr>
<tr><td></td><td>datatables/deregister/{datatable}</td><td><a href="#datatables_deregister">Deregister Data Table</a></td><td></td><td></td><td></td></tr>
@@ -1,56 +0,0 @@
package org.mifosplatform.organisation.staff.command;
import java.util.ArrayList;
import java.util.List;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
/**
* Immutable command for creating or updating details of a staff member.
*/
public class StaffCommand {
private final String firstname;
private final String lastname;
private final Long officeId;
private final Boolean isLoanOfficer;
public StaffCommand(final Long officeId, final String firstName, final String lastName, final Boolean isLoanOfficer) {
this.firstname = firstName;
this.lastname = lastName;
this.officeId = officeId;
this.isLoanOfficer = isLoanOfficer;
}
public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("staff");
baseDataValidator.reset().parameter("firstname").value(this.firstname).notBlank().notExceedingLengthOf(50);
baseDataValidator.reset().parameter("lastname").value(this.lastname).notBlank().notExceedingLengthOf(50);
baseDataValidator.reset().parameter("officeId").value(this.officeId).notNull().integerGreaterThanZero();
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
public void validateForUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("staff");
baseDataValidator.reset().parameter("officeId").value(this.officeId).ignoreIfNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("firstname").value(this.firstname).ignoreIfNull().notBlank().notExceedingLengthOf(50);
baseDataValidator.reset().parameter("lastname").value(this.lastname).ignoreIfNull().notBlank().notExceedingLengthOf(50);
baseDataValidator.reset().parameter("loanOfficerFlag").value(this.isLoanOfficer).ignoreIfNull();
baseDataValidator.reset().anyOfNotNull(this.firstname, this.lastname, this.officeId, this.isLoanOfficer);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
}
@@ -1,28 +1,27 @@
package org.mifosplatform.organisation.staff.serialization;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.staff.command.StaffCommand;
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 StaffCommand}'s.
*/
@Component
public final class StaffCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<StaffCommand> {
public final class StaffCommandFromApiJsonDeserializer {
/**
* The parameters supported for this command.
@@ -36,20 +35,69 @@ public final class StaffCommandFromApiJsonDeserializer extends AbstractFromApiJs
this.fromApiJsonHelper = fromApiJsonHelper;
}
@Override
public StaffCommand commandFromApiJson(final String json) {
public void validateForCreate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("staff");
final JsonElement element = fromApiJsonHelper.parse(json);
final String firstname = fromApiJsonHelper.extractStringNamed("firstname", element);
final String lastname = fromApiJsonHelper.extractStringNamed("lastname", element);
final Boolean isLoanOfficer = fromApiJsonHelper.extractBooleanNamed("isLoanOfficer", element);
final Long officeId = fromApiJsonHelper.extractLongNamed("officeId", element);
baseDataValidator.reset().parameter("firstname").value(firstname).notBlank().notExceedingLengthOf(50);
return new StaffCommand(officeId, firstname, lastname, isLoanOfficer);
final String lastname = fromApiJsonHelper.extractStringNamed("lastname", element);
baseDataValidator.reset().parameter("lastname").value(lastname).notBlank().notExceedingLengthOf(50);
final Long officeId = fromApiJsonHelper.extractLongNamed("officeId", element);
baseDataValidator.reset().parameter("officeId").value(officeId).notNull().integerGreaterThanZero();
if (fromApiJsonHelper.parameterExists("isLoanOfficer", element)) {
final Boolean loanOfficerFlag = fromApiJsonHelper.extractBooleanNamed("isLoanOfficer", element);
baseDataValidator.reset().parameter("isLoanOfficer").value(loanOfficerFlag).notNull();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateForUpdate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("staff");
final JsonElement element = fromApiJsonHelper.parse(json);
if (fromApiJsonHelper.parameterExists("firstname", element)) {
final String firstname = fromApiJsonHelper.extractStringNamed("firstname", element);
baseDataValidator.reset().parameter("firstname").value(firstname).notBlank().notExceedingLengthOf(50);
}
if (fromApiJsonHelper.parameterExists("lastname", element)) {
final String lastname = fromApiJsonHelper.extractStringNamed("lastname", element);
baseDataValidator.reset().parameter("lastname").value(lastname).notBlank().notExceedingLengthOf(50);
}
if (fromApiJsonHelper.parameterExists("officeId", element)) {
final Long officeId = fromApiJsonHelper.extractLongNamed("officeId", element);
baseDataValidator.reset().parameter("officeId").value(officeId).notNull().integerGreaterThanZero();
}
if (fromApiJsonHelper.parameterExists("isLoanOfficer", element)) {
final Boolean loanOfficerFlag = fromApiJsonHelper.extractBooleanNamed("isLoanOfficer", element);
baseDataValidator.reset().parameter("isLoanOfficer").value(loanOfficerFlag).notNull();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
}
@@ -11,7 +11,6 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.office.domain.OfficeRepository;
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
import org.mifosplatform.organisation.staff.command.StaffCommand;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.organisation.staff.domain.StaffRepository;
import org.mifosplatform.organisation.staff.exception.StaffNotFoundException;
@@ -50,8 +49,7 @@ public class StaffWritePlatformServiceJpaRepositoryImpl implements StaffWritePla
try {
context.authenticatedUser();
final StaffCommand staffCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
staffCommand.validateForCreate();
this.fromApiJsonDeserializer.validateForCreate(command.json());
final Long officeId = command.longValueOfParameterNamed("officeId");
@@ -62,8 +60,10 @@ public class StaffWritePlatformServiceJpaRepositoryImpl implements StaffWritePla
this.staffRepository.save(staff);
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(staff.getId())
.withOfficeId(officeId).build();
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(staff.getId()).withOfficeId(officeId) //
.build();
} catch (DataIntegrityViolationException dve) {
handleStaffDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty();
@@ -77,8 +77,7 @@ public class StaffWritePlatformServiceJpaRepositoryImpl implements StaffWritePla
try {
context.authenticatedUser();
final StaffCommand staffCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
staffCommand.validateForUpdate();
this.fromApiJsonDeserializer.validateForUpdate(command.json());
final Staff staffForUpdate = this.staffRepository.findOne(staffId);
if (staffForUpdate == null) { throw new StaffNotFoundException(staffId); }
@@ -42,15 +42,15 @@ public final class FundCommandFromApiJsonDeserializer {
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("code");
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("fund");
final JsonElement element = fromApiJsonHelper.parse(json);
final String name = fromApiJsonHelper.extractStringNamed("name", element);
baseDataValidator.reset().parameter("name").value(name).notBlank().notExceedingLengthOf(255);
baseDataValidator.reset().parameter("name").value(name).notBlank().notExceedingLengthOf(100);
final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element);
baseDataValidator.reset().parameter("externalId").value(externalId).notExceedingLengthOf(255);
baseDataValidator.reset().parameter("externalId").value(externalId).notExceedingLengthOf(100);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
@@ -62,12 +62,12 @@ public final class FundCommandFromApiJsonDeserializer {
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("code");
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("fund");
final JsonElement element = fromApiJsonHelper.parse(json);
if (fromApiJsonHelper.parameterExists("name", element)) {
final String name = fromApiJsonHelper.extractStringNamed("name", element);
baseDataValidator.reset().parameter("name").value(name).notBlank().notExceedingLengthOf(255);
baseDataValidator.reset().parameter("name").value(name).notBlank().notExceedingLengthOf(100);
}
if (fromApiJsonHelper.parameterExists("externalId", element)) {