Added assign/unassign loanofficerto group and update api docs
This commit is contained in:
@@ -208,6 +208,98 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flybar-nav">
|
||||
<h2 class="flybar-button">Group</h2>
|
||||
<div id="toc-menu-client" class="flybar-menu">
|
||||
<div class="tocMatrix">
|
||||
<table class=matrixHeading>
|
||||
<tr class="matrixHeadingBG">
|
||||
<td colspan=2 valign="top"><div class="matrixHeadingVerbs">
|
||||
<table>
|
||||
<tr>
|
||||
<td>RESOURCES</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div></td>
|
||||
<td><table>
|
||||
<tr>
|
||||
<td><div class="matrixHeadingVerbs">POST</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class=matrixHeadingCommands>create/complex
|
||||
update</div></td>
|
||||
</tr>
|
||||
</table></td>
|
||||
<td><table>
|
||||
<tr>
|
||||
<td><div class="matrixHeadingVerbs">GET</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class=matrixHeadingCommands>read</div></td>
|
||||
</tr>
|
||||
</table></td>
|
||||
<td><table>
|
||||
<tr>
|
||||
<td><div class="matrixHeadingVerbs">PUT</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class=matrixHeadingCommands>update</div></td>
|
||||
</tr>
|
||||
</table></td>
|
||||
<td><table>
|
||||
<tr>
|
||||
<td><div class="matrixHeadingVerbs">DELETE</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class=matrixHeadingCommands>delete</div></td>
|
||||
</tr>
|
||||
</table></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td><a href="#groups">GROUP</a></td>
|
||||
<td>groups</td>
|
||||
<td><a href="#groups_create">Create a Group</a></td>
|
||||
<td><a href="#groups_list">List Groups</a></td>
|
||||
<td></td>
|
||||
<td><a href="#groups_delete">Delete a Group</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>groups/{group}</td>
|
||||
<td></td>
|
||||
<td><a href="#groups_retrieve">Retrieve a Group</a></td>
|
||||
<td><a href="#groups_update">Update a Group</a></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td></td>
|
||||
<td>groups/{group}/loans</td>
|
||||
<td></td>
|
||||
<td><a href="#groups_loansummary">Retrieve a Group's
|
||||
Loan Account Summary</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>groups/{group}/command/assign_loanofficer</td>
|
||||
<td><a href="#groups_assignlo">Assign a Loan Officer</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td></td>
|
||||
<td>groups/{group}/command/unassign_loanofficer</td>
|
||||
<td><a href="#groups_unassign_lo">Unassign a Loan Officer</a></td>
|
||||
<td></a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flybar-nav">
|
||||
<h2 class="flybar-button">Loan</h2>
|
||||
<div id="toc-menu-loan" class="flybar-menu">
|
||||
@@ -2011,6 +2103,308 @@ Request Body:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- start of Groups api docs -->
|
||||
<a id="groups" name="groups" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h3>Groups</h3>
|
||||
<p>Groups are collection of clients for specific purpose (JLG,SHG, Program etc) </p>
|
||||
<table class=matrixHeading>
|
||||
<tr class="matrixHeadingBG">
|
||||
<td><div class="mifosXHeading2">Field Descriptions</div></td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>office_id</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>It stores the officeid of office, to this officer Group belongs.</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>loan_officer_id</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>Id of the officer who manages this group.</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>name</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>Human friendly identity of the Group (Name given to the group).</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>externalId</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>A place to put an external reference for
|
||||
this group e.g. The ID another system uses.<br> If
|
||||
provided, it must be unique.
|
||||
</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>is_deleted</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>Indicator for active or archived groups.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<a id="groups_create" name="groups_create" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Create a Group</h4>
|
||||
<table class=matrixHeading>
|
||||
<tr class="matrixHeadingBG">
|
||||
<td><div class="mifosXHeading2">Mandatory Fields</div></td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>name<br>
|
||||
officeId<br>
|
||||
clients
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
POST https://DomainName/mifosng-provider/api/v1/groups
|
||||
</code>
|
||||
<code class="method-request">
|
||||
POST groups
|
||||
Content-Type: application/json Request Body:
|
||||
{
|
||||
"officeId":"1",
|
||||
"name":"TA Group",
|
||||
"externalId":"",
|
||||
"clientMembers":["82","83","84"]
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{"resourceId":24,"changes":{}}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<a id="groups_list" name="groups_list" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>List Groups</h4>
|
||||
<p>Example Requests:</p>
|
||||
<div class=apiClick>groups</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
GET https://DomainName/mifosng-provider/api/v1/groups
|
||||
</code>
|
||||
<code class="method-response">
|
||||
[{
|
||||
"id": 1,
|
||||
"name": "GWT_2",
|
||||
"externalId": "GWT_EX_ID_2",
|
||||
"officeId": 7,
|
||||
"officeName": "Z2"
|
||||
}, {
|
||||
"id": 2,
|
||||
"name": "group22",
|
||||
"externalId": "11234",
|
||||
"officeId": 1,
|
||||
"officeName": "Head Office"
|
||||
}, {
|
||||
"id": 3,
|
||||
"name": "PlusOne",
|
||||
"officeId": 22,
|
||||
"officeName": "North Point Office"
|
||||
}]
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<a id="groups_retrieve" name="groups_retrieve"
|
||||
class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Retrieve a Group</h4>
|
||||
<p>Example Requests:</p>
|
||||
<div class=apiClick>groups/10</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
GET https://DomainName/mifosng-provider/api/v1/groups/10
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"id": 10,
|
||||
"name": "test123",
|
||||
"externalId": "tejjjst",
|
||||
"officeId": 1,
|
||||
"officeName": "Head Office",
|
||||
"clientMembers": [{
|
||||
"id": 1,
|
||||
"displayName": "Willie O\u0027Meara"
|
||||
}]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<a id="groups_loansummary" name="groups_loansummary"
|
||||
class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Retrieve a Groups's Loan Account Summary</h4>
|
||||
<p>
|
||||
An example of how a loan portfolio summary can be provided. This
|
||||
one contains quite a bit of redundant data (like the counts)
|
||||
</p>
|
||||
<p>Example Requests:</p>
|
||||
<div class=apiClick>groups/7/loans</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
GET https://DomainName/mifosng-provider/api/v1/groups/7/loans
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"anyLoanCount": 1,
|
||||
"pendingApprovalLoanCount": 0,
|
||||
"pendingApprovalLoans": [],
|
||||
"awaitingDisbursalLoanCount": 0,
|
||||
"awaitingDisbursalLoans": [],
|
||||
"activeLoanCount": 1,
|
||||
"openLoans": [{
|
||||
"id": 79,
|
||||
"productId": 1,
|
||||
"productName": "1-PORetailLoan",
|
||||
"accountStatusId": 300
|
||||
}],
|
||||
"closedLoanCount": 0,
|
||||
"closedLoans": [],
|
||||
"anyIndividualLoanCount": 3,
|
||||
"pendingApprovalIndividualLoanCount": 0,
|
||||
"pendingApprovalIndividualLoans": [],
|
||||
"awaitingDisbursalIndividualLoanCount": 0,
|
||||
"awaitingDisbursalIndividualLoans": [],
|
||||
"activeIndividualLoanCount": 3,
|
||||
"openIndividualLoans": [{
|
||||
"id": 80,
|
||||
"productId": 17,
|
||||
"productName": "17-Intrasoft Business Loan",
|
||||
"accountStatusId": 300
|
||||
}, {
|
||||
"id": 81,
|
||||
"productId": 1,
|
||||
"productName": "1-PORetailLoan",
|
||||
"accountStatusId": 300
|
||||
}, {
|
||||
"id": 82,
|
||||
"productId": 13,
|
||||
"productName": "13-A Flat Loan",
|
||||
"accountStatusId": 300
|
||||
}],
|
||||
"closedIndividualLoanCount": 0,
|
||||
"closedIndividualLoans": []
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<a id="groups_update" name="groups_update" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Update a Group</h4>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
PUT https://DomainName/mifosng-provider/api/v1/groups/{groupid}
|
||||
</code>
|
||||
<code class="method-request">
|
||||
PUT groups/7
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"officeId": "26",
|
||||
"name": "Laxmi SSG U",
|
||||
"externalId": "Unq 2--124",
|
||||
"clientMembers": ["91", "93", "94"]
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"resourceId":7,
|
||||
"changes":{}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<a id="groups_assignlo" name="groups_assignlo" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Assign a Loan Officer to Group</h4>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
POST https://DomainName/mifosng-provider/api/v1/groups/{groupid}/command/assign_loanofficer
|
||||
</code>
|
||||
<code class="method-request">
|
||||
POST groups/20/command/assign_loanofficer
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
{"loanOfficerId":"1"}
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"resourceId":20,
|
||||
"changes":{}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<a id="groups_unassign_lo" name="groups_unassign_lo" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Unassign a loan officer to a Group</h4>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
POST https://DomainName/mifosng-provider/api/v1/groups/{groupid}/command/assign_loanofficer
|
||||
</code>
|
||||
<code class="method-request">
|
||||
POST groups/20/command/unassign_loanofficer
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
{"loanOfficerId":"1"}
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"resourceId":20,
|
||||
"changes":{}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<a id="groups_delete" name="groups_delete" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Delete a Group</h4>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
POST https://DomainName/mifosng-provider/api/v1/groups/{groupid}
|
||||
</code>
|
||||
<code class="method-request">
|
||||
DELETE groups/7
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"resourceId":7,
|
||||
"changes":{}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<!-- group end anchor grpxxxx -->
|
||||
|
||||
<!-- start of loans api docs -->
|
||||
|
||||
<a id="loans" name="loans" class="old-syle-anchor"> </a>
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
@Table(name = "m_staff", uniqueConstraints = { @UniqueConstraint(columnNames = { "display_name" }, name = "display_name") })
|
||||
public class Staff extends AbstractPersistable<Long> {
|
||||
|
||||
|
||||
@Column(name = "firstname", length = 50)
|
||||
private String firstname;
|
||||
|
||||
|
||||
+13
-1
@@ -7,8 +7,20 @@ package org.mifosplatform.organisation.staff.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface StaffRepository extends JpaRepository<Staff, Long>,
|
||||
JpaSpecificationExecutor<Staff> {
|
||||
// no added behaviour
|
||||
|
||||
public final static String FIND_BY_OFFICE_QUERY = "select s from Staff s where s.id = :id AND s.office.id = :officeId";
|
||||
|
||||
/**
|
||||
* Find staff by officeid.
|
||||
*/
|
||||
@Query(FIND_BY_OFFICE_QUERY)
|
||||
public Staff findByOffice(@Param("id") Long id, @Param("officeId") Long officeId);
|
||||
|
||||
|
||||
|
||||
}
|
||||
+33
@@ -24,9 +24,12 @@ import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||
import org.mifosplatform.commands.service.CommandWrapperBuilder;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
@@ -165,6 +168,32 @@ public class GroupsApiResource {
|
||||
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{groupId}/command/assign_loanofficer")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String assignLoanOfficer(@PathParam("groupId") final Long groupId, final String jsonRequestBody) {
|
||||
|
||||
final GroupCommand command = this.apiDataConversionService.convertJsonToGroupCommand(groupId, jsonRequestBody);
|
||||
|
||||
CommandProcessingResult entityIdentifier = this.groupWritePlatformService.assignLoanOfficer(command);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{groupId}/command/unassign_loanofficer")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String unassignLoanOfficer(@PathParam("groupId") final Long groupId, final String jsonRequestBody) {
|
||||
|
||||
final GroupCommand command = this.apiDataConversionService.convertJsonToGroupCommand(groupId, jsonRequestBody);
|
||||
|
||||
CommandProcessingResult entityIdentifier = this.groupWritePlatformService.unassignLoanOfficer(command);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{groupId}")
|
||||
@@ -243,4 +272,8 @@ public class GroupsApiResource {
|
||||
|
||||
return extraCriteria;
|
||||
}
|
||||
|
||||
private boolean is(final String commandParam, final String commandValue) {
|
||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
||||
}
|
||||
}
|
||||
+17
@@ -59,4 +59,21 @@ public class GroupCommandValidator {
|
||||
}
|
||||
}
|
||||
|
||||
public void validateForLoanOfficerUpdate() {
|
||||
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("group");
|
||||
|
||||
baseDataValidator.reset().parameter("id").value(command.getId()).notNull();
|
||||
|
||||
if (command.isLoanOfficerChanged()) {
|
||||
baseDataValidator.reset().parameter("loanOfficerId").value(command.getLoanOfficeId()).notNull().integerGreaterThanZero();
|
||||
}
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class Group extends AbstractPersistable<Long> {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "loan_officer_id", nullable = false)
|
||||
@JoinColumn(name = "loan_officer_id", nullable = true)
|
||||
private Staff loanOfficer;
|
||||
|
||||
@Column(name = "name", length = 100, unique = true)
|
||||
@@ -78,6 +78,14 @@ public class Group extends AbstractPersistable<Long> {
|
||||
}
|
||||
}
|
||||
|
||||
public Long getOfficeId() {
|
||||
return this.office.getId();
|
||||
}
|
||||
|
||||
public Long getLoanOfficerId() {
|
||||
return this.loanOfficer.getId();
|
||||
}
|
||||
|
||||
public void update(final GroupCommand command, final Office groupOffice, final Staff newLoanOfficer, final Set<Client> clientMembers) {
|
||||
if (command.isExternalIdChanged()) {
|
||||
this.externalId = command.getExternalId();
|
||||
@@ -100,6 +108,18 @@ public class Group extends AbstractPersistable<Long> {
|
||||
}
|
||||
}
|
||||
|
||||
public void assigLoanOfficer(final GroupCommand command , final Staff newLoanOfficer){
|
||||
if (command.isLoanOfficerChanged()) {
|
||||
this.loanOfficer = newLoanOfficer;
|
||||
}
|
||||
}
|
||||
|
||||
public void unassigLoanOfficer(GroupCommand command) {
|
||||
if (command.isLoanOfficerChanged()) {
|
||||
this.loanOfficer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void addClientMember(final Client member) {
|
||||
this.clientMembers.add(member);
|
||||
}
|
||||
@@ -123,4 +143,5 @@ public class Group extends AbstractPersistable<Long> {
|
||||
public boolean isDeleted() {
|
||||
return deleted;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
@@ -19,5 +19,11 @@ public interface GroupWritePlatformService {
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_GROUP')")
|
||||
CommandProcessingResult deleteGroup(Long groupId);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_GROUP')")
|
||||
CommandProcessingResult assignLoanOfficer(GroupCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_GROUP')")
|
||||
CommandProcessingResult unassignLoanOfficer(GroupCommand command);
|
||||
|
||||
}
|
||||
|
||||
+137
-65
@@ -52,12 +52,12 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
|
||||
|
||||
@Autowired
|
||||
public GroupWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final GroupRepository groupRepository,
|
||||
final ClientRepository clientRepository, final OfficeRepository officeRepository , final StaffRepository staffRepository) {
|
||||
final ClientRepository clientRepository, final OfficeRepository officeRepository, final StaffRepository staffRepository) {
|
||||
this.context = context;
|
||||
this.groupRepository = groupRepository;
|
||||
this.clientRepository = clientRepository;
|
||||
this.officeRepository = officeRepository;
|
||||
this.staffRepository = staffRepository;
|
||||
this.staffRepository = staffRepository;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -66,35 +66,29 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
GroupCommandValidator validator = new GroupCommandValidator(command);
|
||||
final GroupCommandValidator validator = new GroupCommandValidator(command);
|
||||
validator.validateForCreate();
|
||||
|
||||
Office groupOffice = this.officeRepository.findOne(command.getOfficeId());
|
||||
|
||||
final Office groupOffice = this.officeRepository.findOne(command.getOfficeId());
|
||||
|
||||
Staff loanOfficer = null;
|
||||
Long loanOfficerId = command.getLoanOfficeId();
|
||||
|
||||
final Long loanOfficerId = command.getLoanOfficeId();
|
||||
|
||||
if (groupOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); }
|
||||
|
||||
if (loanOfficerId != null) {
|
||||
// TODO Set the scope for staffRepository.findOneByOfficeId to a officer equal to groupOffice
|
||||
loanOfficer = this.staffRepository.findOne(loanOfficerId);
|
||||
if (loanOfficer == null) {
|
||||
throw new StaffNotFoundException(loanOfficerId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (groupOffice == null) {
|
||||
throw new OfficeNotFoundException(command.getOfficeId());
|
||||
loanOfficer = this.staffRepository.findByOffice(loanOfficerId, command.getOfficeId());
|
||||
if (loanOfficer == null) { throw new StaffNotFoundException(loanOfficerId); }
|
||||
}
|
||||
|
||||
final Set<Client> clientMembers = assembleSetOfClients(command);
|
||||
|
||||
Group newGroup = Group.newGroup(groupOffice, loanOfficer , command.getName(), command.getExternalId(), clientMembers);
|
||||
final Group newGroup = Group.newGroup(groupOffice, loanOfficer, command.getName(), command.getExternalId(), clientMembers);
|
||||
|
||||
this.groupRepository.saveAndFlush(newGroup);
|
||||
|
||||
return new CommandProcessingResult(newGroup.getId());
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
} catch (final DataIntegrityViolationException dve) {
|
||||
handleGroupDataIntegrityIssues(command, dve);
|
||||
return new CommandProcessingResult(Long.valueOf(-1));
|
||||
}
|
||||
@@ -105,58 +99,136 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
|
||||
public CommandProcessingResult updateGroup(final GroupCommand command) {
|
||||
|
||||
try {
|
||||
context.authenticatedUser();
|
||||
this.context.authenticatedUser();
|
||||
|
||||
GroupCommandValidator validator = new GroupCommandValidator(command);
|
||||
final GroupCommandValidator validator = new GroupCommandValidator(command);
|
||||
validator.validateForUpdate();
|
||||
|
||||
Group groupForUpdate = this.groupRepository.findOne(command.getId());
|
||||
if (groupForUpdate == null || groupForUpdate.isDeleted()) {
|
||||
throw new GroupNotFoundException(command.getId());
|
||||
}
|
||||
final Group groupForUpdate = this.groupRepository.findOne(command.getId());
|
||||
if (groupForUpdate == null || groupForUpdate.isDeleted()) { throw new GroupNotFoundException(command.getId()); }
|
||||
|
||||
Office groupOffice = null;
|
||||
Long officeId = command.getOfficeId();
|
||||
if (command.isOfficeIdChanged() && officeId != null) {
|
||||
groupOffice = this.officeRepository.findOne(officeId);
|
||||
if (groupOffice == null) {
|
||||
throw new OfficeNotFoundException(command.getOfficeId());
|
||||
}
|
||||
}
|
||||
|
||||
final Long officeId = command.getOfficeId();
|
||||
Staff loanOfficer = null;
|
||||
Long loanOfficerId = command.getLoanOfficeId();
|
||||
if (command.isLoanOfficerChanged() && loanOfficerId != null) {
|
||||
loanOfficer = this.staffRepository.findOne(loanOfficerId);
|
||||
if (loanOfficer == null) {
|
||||
throw new LoanOfficerNotFoundException(loanOfficerId);
|
||||
final Long loanOfficerId = command.getLoanOfficeId();
|
||||
|
||||
if (command.isOfficeIdChanged() && command.isLoanOfficerChanged()) {
|
||||
/**
|
||||
* Scenario: Both Office and loan officer are changed, check new
|
||||
* loan officer is present in new office
|
||||
*/
|
||||
if (officeId != null) {
|
||||
groupOffice = this.officeRepository.findOne(officeId);
|
||||
if (groupOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); }
|
||||
}
|
||||
if (loanOfficerId != null) {
|
||||
loanOfficer = this.staffRepository.findByOffice(loanOfficerId, officeId);
|
||||
if (loanOfficer == null) { throw new LoanOfficerNotFoundException(loanOfficerId); }
|
||||
}
|
||||
|
||||
} else if (command.isOfficeIdChanged()) {
|
||||
/**
|
||||
* Scenario: Only Office is changed, check new office has
|
||||
* present loan officer, This situation is not practical as loan
|
||||
* officer can't be present in two offices
|
||||
*/
|
||||
// TODO When office is changed need to make sure all the loan
|
||||
// officer at loan level are also updated or verified
|
||||
|
||||
if (officeId != null) {
|
||||
groupOffice = this.officeRepository.findOne(officeId);
|
||||
if (groupOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); }
|
||||
}
|
||||
if (loanOfficerId != null) {
|
||||
loanOfficer = this.staffRepository.findByOffice(loanOfficerId, groupForUpdate.getOfficeId());
|
||||
if (loanOfficer == null) { throw new LoanOfficerNotFoundException(loanOfficerId); }
|
||||
}
|
||||
|
||||
} else if (command.isLoanOfficerChanged()) {
|
||||
/**
|
||||
* Scenario: Only Loan Officer is changed, check new new loan
|
||||
* officer is in present assigned office
|
||||
*/
|
||||
if (loanOfficerId != null) {
|
||||
loanOfficer = this.staffRepository.findByOffice(loanOfficerId, groupForUpdate.getOfficeId());
|
||||
if (loanOfficer == null) { throw new LoanOfficerNotFoundException(loanOfficerId); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final Set<Client> clientMembers = assembleSetOfClients(command);
|
||||
|
||||
groupForUpdate.update(command, groupOffice, loanOfficer , clientMembers);
|
||||
groupForUpdate.update(command, groupOffice, loanOfficer, clientMembers);
|
||||
|
||||
groupRepository.saveAndFlush(groupForUpdate);
|
||||
this.groupRepository.saveAndFlush(groupForUpdate);
|
||||
|
||||
return new CommandProcessingResult(groupForUpdate.getId());
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
} catch (final DataIntegrityViolationException dve) {
|
||||
handleGroupDataIntegrityIssues(command, dve);
|
||||
return new CommandProcessingResult(Long.valueOf(-1));
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
|
||||
public CommandProcessingResult assignLoanOfficer(final GroupCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final GroupCommandValidator validator = new GroupCommandValidator(command);
|
||||
validator.validateForLoanOfficerUpdate();
|
||||
|
||||
final Group groupForUpdate = this.groupRepository.findOne(command.getId());
|
||||
if (groupForUpdate == null || groupForUpdate.isDeleted()) { throw new GroupNotFoundException(command.getId()); }
|
||||
|
||||
Staff loanOfficer = null;
|
||||
final Long loanOfficerId = command.getLoanOfficeId();
|
||||
if (command.isLoanOfficerChanged() && loanOfficerId != null) {
|
||||
loanOfficer = this.staffRepository.findByOffice(loanOfficerId, groupForUpdate.getOfficeId());
|
||||
if (loanOfficer == null) { throw new LoanOfficerNotFoundException(loanOfficerId); }
|
||||
}
|
||||
|
||||
groupForUpdate.assigLoanOfficer(command, loanOfficer);
|
||||
|
||||
this.groupRepository.saveAndFlush(groupForUpdate);
|
||||
|
||||
return new CommandProcessingResult(groupForUpdate.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult unassignLoanOfficer(final GroupCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final GroupCommandValidator validator = new GroupCommandValidator(command);
|
||||
validator.validateForLoanOfficerUpdate();
|
||||
|
||||
final Group groupForUpdate = this.groupRepository.findOne(command.getId());
|
||||
if (groupForUpdate == null || groupForUpdate.isDeleted()) { throw new GroupNotFoundException(command.getId()); }
|
||||
|
||||
final Long loanOfficerId = command.getLoanOfficeId();
|
||||
final Long presentLoanOfficerId = groupForUpdate.getLoanOfficerId();
|
||||
|
||||
if (command.isLoanOfficerChanged() && loanOfficerId != null) {
|
||||
if (!loanOfficerId.equals(presentLoanOfficerId)) { throw new LoanOfficerNotFoundException(loanOfficerId); }
|
||||
}
|
||||
|
||||
groupForUpdate.unassigLoanOfficer(command);
|
||||
|
||||
this.groupRepository.saveAndFlush(groupForUpdate);
|
||||
|
||||
return new CommandProcessingResult(groupForUpdate.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult deleteGroup(final Long groupId) {
|
||||
|
||||
context.authenticatedUser();
|
||||
this.context.authenticatedUser();
|
||||
|
||||
Group groupForDelete = this.groupRepository.findOne(groupId);
|
||||
if (groupForDelete == null || groupForDelete.isDeleted()) {
|
||||
throw new GroupNotFoundException(groupId);
|
||||
}
|
||||
final Group groupForDelete = this.groupRepository.findOne(groupId);
|
||||
if (groupForDelete == null || groupForDelete.isDeleted()) { throw new GroupNotFoundException(groupId); }
|
||||
groupForDelete.delete();
|
||||
this.groupRepository.save(groupForDelete);
|
||||
|
||||
@@ -165,18 +237,16 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
|
||||
|
||||
private Set<Client> assembleSetOfClients(final GroupCommand command) {
|
||||
|
||||
Set<Client> clientMembers = new HashSet<Client>();
|
||||
String[] clientMembersArray = command.getClientMembers();
|
||||
final Set<Client> clientMembers = new HashSet<Client>();
|
||||
final String[] clientMembersArray = command.getClientMembers();
|
||||
|
||||
if (command.isClientMembersChanged() && !ObjectUtils.isEmpty(clientMembersArray)) {
|
||||
for (String clientId : clientMembersArray) {
|
||||
for (final String clientId : clientMembersArray) {
|
||||
final Long id = Long.valueOf(clientId);
|
||||
Client client = this.clientRepository.findOne(id);
|
||||
if (client == null || client.isDeleted()) {
|
||||
throw new ClientNotFoundException(id);
|
||||
}
|
||||
if (!client.isOfficeIdentifiedBy(command.getOfficeId())){
|
||||
String errorMessage = "Group and Client must have the same office.";
|
||||
final Client client = this.clientRepository.findOne(id);
|
||||
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(id); }
|
||||
if (!client.isOfficeIdentifiedBy(command.getOfficeId())) {
|
||||
final String errorMessage = "Group and Client must have the same office.";
|
||||
throw new InvalidOfficeException("client", "attach.to.group", errorMessage);
|
||||
}
|
||||
clientMembers.add(client);
|
||||
@@ -187,18 +257,20 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
|
||||
}
|
||||
|
||||
/*
|
||||
* Guaranteed to throw an exception no matter what the data integrity issue is.
|
||||
*/
|
||||
private void handleGroupDataIntegrityIssues(final GroupCommand command, final DataIntegrityViolationException dve) {
|
||||
* Guaranteed to throw an exception no matter what the data integrity issue
|
||||
* is.
|
||||
*/
|
||||
private void handleGroupDataIntegrityIssues(final GroupCommand command, final DataIntegrityViolationException dve) {
|
||||
|
||||
Throwable realCause = dve.getMostSpecificCause();
|
||||
final Throwable realCause = dve.getMostSpecificCause();
|
||||
if (realCause.getMessage().contains("external_id")) {
|
||||
throw new PlatformDataIntegrityException("error.msg.group.duplicate.externalId", "Group with externalId {0} already exists", "externalId", command.getExternalId());
|
||||
} else if (realCause.getMessage().contains("name")) {
|
||||
throw new PlatformDataIntegrityException("error.msg.group.duplicate.name", "Group with name {0} already exists", "name", command.getName());
|
||||
}
|
||||
throw new PlatformDataIntegrityException("error.msg.group.duplicate.externalId", "Group with externalId {0} already exists",
|
||||
"externalId", command.getExternalId());
|
||||
} else if (realCause.getMessage().contains("name")) { throw new PlatformDataIntegrityException("error.msg.group.duplicate.name",
|
||||
"Group with name {0} already exists", "name", command.getName()); }
|
||||
|
||||
logger.error(dve.getMessage(), dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.group.unknown.data.integrity.issue", "Unknown data integrity issue with resource.");
|
||||
throw new PlatformDataIntegrityException("error.msg.group.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource.");
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -75,7 +75,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
|
||||
final Set<String> modifiedParameters = new HashSet<String>();
|
||||
|
||||
final Long officeId = extractLongParameter("officeId", requestMap, modifiedParameters);
|
||||
final Long loanOfficeId = extractLongParameter("loanOfficerId", requestMap, modifiedParameters);
|
||||
final Long loanOfficerId = extractLongParameter("loanOfficerId", requestMap, modifiedParameters);
|
||||
final String externalId = extractStringParameter("externalId", requestMap, modifiedParameters);
|
||||
final String name = extractStringParameter("name", requestMap, modifiedParameters);
|
||||
|
||||
@@ -97,7 +97,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
|
||||
}
|
||||
//
|
||||
|
||||
return new GroupCommand(modifiedParameters, resourceIdentifier, externalId, name, officeId, loanOfficeId , clientMembers);
|
||||
return new GroupCommand(modifiedParameters, resourceIdentifier, externalId, name, officeId, loanOfficerId , clientMembers);
|
||||
}
|
||||
|
||||
private void checkForUnsupportedParameters(Map<String, ?> requestMap, Set<String> supportedParams) {
|
||||
|
||||
Reference in New Issue
Block a user