MIFOSX-213: support pending, active, closed status for clients.
This commit is contained in:
+283
-150
@@ -176,6 +176,14 @@
|
||||
<td></td>
|
||||
<td><a href="#clients_retrieve">Retrieve a Client</a></td>
|
||||
<td><a href="#clients_update">Update a Client</a></td>
|
||||
<td><a href="#clients_delete">Delete a Client</a></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td></td>
|
||||
<td>clients/{clientId}?command=activate</td>
|
||||
<td><a href="#clients_activate">Activate a Client</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
@@ -1697,8 +1705,8 @@ function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFuncti
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h3>Clients</h3>
|
||||
<p>Clients are people and businesses that have applied (or may
|
||||
apply) to an MFI for loans.</p>
|
||||
<p>Clients are people and businesses that have applied (or may apply) to an MFI for loans.</p>
|
||||
<p>Clients can be created in <b>Pending</b> state (as opposed to <b>Active</b> state) if global configuration for <i>allow-pending-client-status</i> is enabled.</p>
|
||||
<table class=matrixHeading>
|
||||
<tr class="matrixHeadingBG">
|
||||
<td><div class="mifosXHeading2">Field Descriptions</div></td>
|
||||
@@ -1712,6 +1720,29 @@ function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFuncti
|
||||
auto generated account no. is put in place based on the
|
||||
configured strategy.</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>externalId</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>A place to put an external reference for
|
||||
this client e.g. The ID another system uses.<br> If
|
||||
provided, it must be unique.
|
||||
</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>active</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>Indicates whether this client is to be created as <b>active</b> client. If active=true, then <b>activationDate</b> must be provided. If active=false, then the client is created as <b>pending</b> but this must be allowed through configuration.
|
||||
</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>activationDate</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>The date on which the client became <b>active</b>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>firstname</td>
|
||||
</tr>
|
||||
@@ -1741,63 +1772,11 @@ function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFuncti
|
||||
business that doesnt suit the firstname,middlename,lastname
|
||||
structure.</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>externalId</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>A place to put an external reference for
|
||||
this client e.g. The ID another system uses.<br> If
|
||||
provided, it must be unique.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="client_list" name="clients_list" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>List Clients</h4>
|
||||
<p>Example Requests:</p>
|
||||
<div class=apiClick>clients</div>
|
||||
<br>
|
||||
<br>
|
||||
<div class=apiClick>clients?fields=displayName,officeName,joinedDate</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
GET https://DomainName/api/v1/clients
|
||||
</code>
|
||||
<code class="method-response">
|
||||
[
|
||||
{
|
||||
"id": 2,
|
||||
"accountNo": "000000002",
|
||||
"externalId": "one/78",
|
||||
"fullname": "New Business to Create",
|
||||
"displayName": "New Business to Create",
|
||||
"officeId": 1,
|
||||
"officeName": "Head Office",
|
||||
"joinedDate": [2006,6,13]
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"accountNo": "000000001",
|
||||
"externalId": "786YYH7",
|
||||
"firstname": "Petra",
|
||||
"lastname": "Yton",
|
||||
"displayName": "Petra Yton",
|
||||
"officeId": 1,
|
||||
"officeName": "Head Office",
|
||||
"joinedDate": [2009,3,4]
|
||||
}
|
||||
]
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="clients_template" name="clients_template"
|
||||
class="old-syle-anchor"> </a>
|
||||
<a id="clients_template" name="clients_template" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Retrieve Client Details Template</h4>
|
||||
@@ -1819,58 +1798,20 @@ GET https://DomainName/api/v1/clients/template
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"officeId": 1,
|
||||
"joinedDate": [
|
||||
2013,
|
||||
2,
|
||||
5
|
||||
],
|
||||
"allowedOffices": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Head Office",
|
||||
"nameDecorated": "Head Office"
|
||||
}
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<a id="clients_retrieve" name="clients_retrieve"
|
||||
class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Retrieve a Client</h4>
|
||||
<p>Example Requests:</p>
|
||||
<div class=apiClick>clients/1</div>
|
||||
<br>
|
||||
<br>
|
||||
<div class=apiClick>clients/1?template=true</div>
|
||||
<br>
|
||||
<br>
|
||||
<div class=apiClick>clients/1?fields=id,displayName,officeName</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
GET https://DomainName/api/v1/clients/{clientId}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"id": 1,
|
||||
"accountNo": "000000001",
|
||||
"externalId": "786YYH7",
|
||||
"firstname": "Petra",
|
||||
"lastname": "Yton",
|
||||
"displayName": "Petra Yton",
|
||||
"officeId": 1,
|
||||
"officeName": "Head Office",
|
||||
"joinedDate": [
|
||||
2009,
|
||||
3,
|
||||
4
|
||||
]
|
||||
"activationDate": [
|
||||
2013,
|
||||
4,
|
||||
17
|
||||
],
|
||||
"officeId": 1,
|
||||
"clientPendingApprovalAllowed": false,
|
||||
"officeOptions": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Head Office",
|
||||
"nameDecorated": "Head Office"
|
||||
}
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -1891,11 +1832,19 @@ GET https://DomainName/api/v1/clients/{clientId}
|
||||
<td><div class="mifosXHeading2">Mandatory Fields</div></td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>firstname and lastname OR fullname<br>, joinedDate,
|
||||
officeId
|
||||
<td>firstname and lastname OR fullname,<br> officeId,<br> active=true and activationDate OR active=false,<br>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
<table class=matrixHeading>
|
||||
<tr class="matrixHeadingBG">
|
||||
<td><div class="mifosXHeading2">Optional Fields</div></td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>groupId, externalId, accountNo</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
@@ -1904,14 +1853,15 @@ POST https://DomainName/api/v1/clients
|
||||
<code class="method-request">
|
||||
POST clients
|
||||
Content-Type: application/json Request Body:
|
||||
{
|
||||
"officeId": 1,
|
||||
"firstname": "Petra",
|
||||
"lastname": "Yton",
|
||||
"externalId": "786YYH7",
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"locale": "en",
|
||||
"joinedDate": "04 March 2009"
|
||||
{
|
||||
"officeId": 1,
|
||||
"firstname": "Petra",
|
||||
"lastname": "Yton",
|
||||
"externalId": "786YYH7",
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"locale": "en",
|
||||
"active": true,
|
||||
"activationDate": "04 March 2009"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
@@ -1926,30 +1876,166 @@ Content-Type: application/json Request Body:
|
||||
<code class="method-request">
|
||||
POST clients
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"officeId": 1,
|
||||
"fullname": "New Business to Create",
|
||||
"externalId": "one/78",
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"locale": "en",
|
||||
"joinedDate": "13 June 2006"
|
||||
Request Body:
|
||||
{
|
||||
"officeId": 1,
|
||||
"fullname": "Client of group",
|
||||
"groupId": 1,
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"locale": "en",
|
||||
"active": true,
|
||||
"activationDate": "04 March 2009"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"officeId": 1,
|
||||
"clientId": 2,
|
||||
"resourceId": 2
|
||||
"officeId": 1,
|
||||
"groupId": 1,
|
||||
"clientId": 2,
|
||||
"resourceId": 2
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="clients_activate" name="clients_activate" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h2>Activate a Client</h2>
|
||||
<p>Clients can be created in a <i>Pending</i> state if configuration is enabled. This API exists to enable client activation (for when a client becomes approved member of microfinance institue.</p>
|
||||
<p>If the client happens to be alrady active this API will result in an error.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/clients/{clientId}?command=activate</code>
|
||||
<code class="method-request">POST clients/1?command=activate
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"locale": "en",
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"activationDate": "01 March 2011"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"officeId": 1,
|
||||
"clientId": 1,
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="clients_retrieve" name="clients_retrieve" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Retrieve a Client</h4>
|
||||
<p>Example Requests:</p>
|
||||
<div class=apiClick>clients/1</div>
|
||||
<br>
|
||||
<br>
|
||||
<div class=apiClick>clients/1?template=true</div>
|
||||
<br>
|
||||
<br>
|
||||
<div class=apiClick>clients/1?fields=id,displayName,officeName</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
GET https://DomainName/api/v1/clients/{clientId}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"id": 2,
|
||||
"accountNo": "000000002",
|
||||
"status": {
|
||||
"id": 300,
|
||||
"code": "clientStatusType.active",
|
||||
"value": "Active"
|
||||
},
|
||||
"activationDate": [
|
||||
2009,
|
||||
3,
|
||||
4
|
||||
],
|
||||
"fullname": "Client of group",
|
||||
"displayName": "Client of group",
|
||||
"officeId": 1,
|
||||
"officeName": "Head Office",
|
||||
"groups": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Example Group"
|
||||
}
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="client_list" name="clients_list" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>List Clients</h4>
|
||||
<p>Example Requests:</p>
|
||||
<div class=apiClick>clients</div>
|
||||
<br>
|
||||
<br>
|
||||
<div class=apiClick>clients?fields=displayName,officeName,joinedDate</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
GET https://DomainName/api/v1/clients
|
||||
</code>
|
||||
<code class="method-response">
|
||||
[
|
||||
{
|
||||
"id": 2,
|
||||
"accountNo": "000000002",
|
||||
"status": {
|
||||
"id": 300,
|
||||
"code": "clientStatusType.active",
|
||||
"value": "Active"
|
||||
},
|
||||
"activationDate": [
|
||||
2009,
|
||||
3,
|
||||
4
|
||||
],
|
||||
"fullname": "Client of group",
|
||||
"displayName": "Client of group",
|
||||
"officeId": 1,
|
||||
"officeName": "Head Office"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"accountNo": "000000001",
|
||||
"externalId": "786YYH7",
|
||||
"status": {
|
||||
"id": 300,
|
||||
"code": "clientStatusType.active",
|
||||
"value": "Active"
|
||||
},
|
||||
"activationDate": [
|
||||
2009,
|
||||
3,
|
||||
4
|
||||
],
|
||||
"firstname": "Petra",
|
||||
"lastname": "Yton",
|
||||
"displayName": "Petra Yton",
|
||||
"officeId": 1,
|
||||
"officeName": "Head Office"
|
||||
}
|
||||
]
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="clients_update" name="clients_update" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Update a Client</h4>
|
||||
<p>You can update any attribute of a client except for its association with <i>groups</i>. The relationship between a client and a group must be removed through the <b>Groups</b> API.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
@@ -1960,10 +2046,7 @@ PUT clients/1
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"externalId": "786444UUUYYH7",
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"locale": "en",
|
||||
"joinedDate": "09 June 2006"
|
||||
"externalId": "786444UUUYYH7"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
@@ -1972,18 +2055,41 @@ Request Body:
|
||||
"clientId": 1,
|
||||
"resourceId": 1,
|
||||
"changes": {
|
||||
"externalId": "786444UUUYYH7",
|
||||
"joinedDate": "09 June 2006",
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"locale": "en"
|
||||
"externalId": "786444UUUYYH7"
|
||||
}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="clients_loansummary" name="clients_loansummary"
|
||||
class="old-syle-anchor"> </a>
|
||||
<a id="clients_delete" name="clients_delete" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Delete a Client</h4>
|
||||
<p>If a client is in <i>Pending</i> state you are allowed to <b>Delete</b> it. The delete is a 'hard delete' and cannot be recovered from. Once clients become active or have loans or savings associated with it, you cannot delete the client but you may <b>Close</b> the client if they have died or exited the program.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
DELETE https://DomainName/api/v1/clients/{clientId}
|
||||
</code>
|
||||
<code class="method-request">
|
||||
DELETE clients/3
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"officeId": 1,
|
||||
"clientId": 3,
|
||||
"resourceId": 3
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="clients_loansummary" name="clients_loansummary" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Retrieve a Client's Loan Account Summary</h4>
|
||||
@@ -7066,13 +7172,16 @@ Request Body:
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h3>Global Configuration</h3>
|
||||
<p>Global configuration related to set of supported
|
||||
enable/disable configurations e.g. maker-checker.</p>
|
||||
<p>Global configuration related to set of supported enable/disable configurations:</p>
|
||||
<ol>
|
||||
<li><b>maker-checker</b> - defaults to false - if true turns on maker-checker functionality</li>
|
||||
<li><b>allow-pending-client-status</b> - defaults to false - if true allows clients to be created in 'Pending' state</li>
|
||||
<li><b>allow-pending-group-status</b> - defaults to false - if true allows groups to be created in 'Pending' state</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="configs_globalconfig_retrieve"
|
||||
name="configs_globalconfig_retrieve" class="old-syle-anchor"> </a>
|
||||
<a id="configs_globalconfig_retrieve" name="configs_globalconfig_retrieve" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Retrieve Global Configuration</h4>
|
||||
@@ -7086,12 +7195,20 @@ GET https://DomainName/api/v1/configurations
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"globalConfiguration": [
|
||||
{
|
||||
"name": "maker-checker",
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
"globalConfiguration": [
|
||||
{
|
||||
"name": "maker-checker",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"name": "allow-pending-client-status",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"name": "allow-pending-group-status",
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -7105,14 +7222,22 @@ GET https://DomainName/api/v1/configurations
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">
|
||||
PUT https://DomainName/api/v1/configurations?maker-checker=false
|
||||
PUT https://DomainName/api/v1/configurations?allow-pending-client-status=false
|
||||
</code>
|
||||
<code class="method-request">
|
||||
PUT configurations
|
||||
Content-Type: application/json
|
||||
Request Body: { }
|
||||
</code>
|
||||
<code class="method-response">{ "changes": {} } </code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"changes": {
|
||||
"globalConfiguration": {
|
||||
"allow-pending-client-status": false
|
||||
}
|
||||
}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12884,6 +13009,14 @@ GET https://DomainName/api/v1/search?query=000000111
|
||||
<td></td>
|
||||
<td><a href="#clients_retrieve">Retrieve a Client</a></td>
|
||||
<td><a href="#clients_update">Update a Client</a></td>
|
||||
<td><a href="#clients_delete">Delete a Client</a></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td></td>
|
||||
<td>clients/{clientId}?command=activate</td>
|
||||
<td><a href="#clients_activate">Activate a Client</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'ACTIVATE_CLIENT', 'CLIENT', 'ACTIVATE', 1);
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'ACTIVATE_CLIENT_CHECKER', 'CLIENT', 'ACTIVATE', 0);
|
||||
|
||||
|
||||
ALTER TABLE `m_client`
|
||||
CHANGE COLUMN `external_id` `external_id` VARCHAR(100) NULL DEFAULT NULL AFTER `account_no`,
|
||||
CHANGE COLUMN `status_enum` `status_enum` INT(5) NOT NULL DEFAULT '300' AFTER `external_id`,
|
||||
CHANGE COLUMN `joined_date` `activation_date` DATE NULL DEFAULT NULL AFTER `status_enum`;
|
||||
+13
-14
@@ -1,29 +1,28 @@
|
||||
package org.mifosplatform.integrationtests;
|
||||
|
||||
|
||||
import com.jayway.restassured.builder.RequestSpecBuilder;
|
||||
import com.jayway.restassured.builder.ResponseSpecBuilder;
|
||||
import com.jayway.restassured.http.ContentType;
|
||||
import com.jayway.restassured.specification.RequestSpecification;
|
||||
import com.jayway.restassured.specification.ResponseSpecification;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mifosplatform.integrationtests.common.*;
|
||||
import org.mifosplatform.integrationtests.common.ClientHelper;
|
||||
import org.mifosplatform.integrationtests.common.Utils;
|
||||
import org.mifosplatform.integrationtests.common.accounting.Account;
|
||||
import org.mifosplatform.integrationtests.common.accounting.JournalEntry;
|
||||
import org.mifosplatform.integrationtests.common.accounting.AccountHelper;
|
||||
import org.mifosplatform.integrationtests.common.accounting.JournalEntry;
|
||||
import org.mifosplatform.integrationtests.common.accounting.JournalEntryHelper;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanApplicationTestBuilder;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanProductTestBuilder;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanStatusChecker;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanTransactionHelper;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
import com.jayway.restassured.builder.RequestSpecBuilder;
|
||||
import com.jayway.restassured.builder.ResponseSpecBuilder;
|
||||
import com.jayway.restassured.http.ContentType;
|
||||
import com.jayway.restassured.specification.RequestSpecification;
|
||||
import com.jayway.restassured.specification.ResponseSpecification;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class AccountingScenario {
|
||||
private RequestSpecification requestSpec;
|
||||
private ResponseSpecification responseSpec;
|
||||
@@ -170,12 +169,12 @@ public class AccountingScenario {
|
||||
System.out.println("Repayment 5 Done ......");
|
||||
}
|
||||
|
||||
private Integer createLoanProduct(Account ... accounts) {
|
||||
private Integer createLoanProduct(final Account ... accounts) {
|
||||
System.out.println("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
|
||||
String loanProductJSON = new LoanProductTestBuilder().withPrincipal(LP_PRINCIPAL.toString()).withRepaymentTypeAsMonth()
|
||||
.withRepaymentAfterEvery(LP_REPAYMENT_PERIOD).withNumberOfRepayments(LP_REPAYMENTS).withRepaymentTypeAsMonth()
|
||||
.withinterestRatePerPeriod(LP_INTEREST_RATE).withInterestRateFrequencyTypeAsMonths()
|
||||
.withAmortizationTypeAsEqualPrinciplePayment().withInterestTypeAsFlat()
|
||||
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat()
|
||||
.withAccountingRuleAsAccrualBased(accounts)
|
||||
.build();
|
||||
return loanTransactionHelper.getLoanProductId(loanProductJSON);
|
||||
|
||||
+4
-7
@@ -1,17 +1,15 @@
|
||||
package org.mifosplatform.integrationtests;
|
||||
|
||||
//import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mifosplatform.integrationtests.common.ClientHelper;
|
||||
import org.mifosplatform.integrationtests.common.Utils;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanApplicationTestBuilder;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanProductTestBuilder;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanStatusChecker;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanTransactionHelper;
|
||||
import org.mifosplatform.integrationtests.common.Utils;
|
||||
|
||||
import com.jayway.restassured.builder.RequestSpecBuilder;
|
||||
import com.jayway.restassured.builder.ResponseSpecBuilder;
|
||||
@@ -19,13 +17,11 @@ import com.jayway.restassured.http.ContentType;
|
||||
import com.jayway.restassured.specification.RequestSpecification;
|
||||
import com.jayway.restassured.specification.ResponseSpecification;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Client Loan Integration Test for checking Loan Disbursement with Waive
|
||||
* Interest and Write-Off.
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
public class LoanWithWaiveInterestAndWriteOffIntegrationTest {
|
||||
|
||||
private ResponseSpecification responseSpec;
|
||||
@@ -120,7 +116,8 @@ public class LoanWithWaiveInterestAndWriteOffIntegrationTest {
|
||||
String loanProductJSON = new LoanProductTestBuilder().withPrincipal(LP_PRINCIPAL).withRepaymentTypeAsMonth()
|
||||
.withRepaymentAfterEvery(LP_REPAYMENT_PERIOD).withNumberOfRepayments(LP_REPAYMENTS).withRepaymentTypeAsMonth()
|
||||
.withinterestRatePerPeriod(LP_INTEREST_RATE).withInterestRateFrequencyTypeAsMonths()
|
||||
.withAmortizationTypeAsEqualPrinciplePayment().withInterestTypeAsFlat().build();
|
||||
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().build();
|
||||
|
||||
return loanTransactionHelper.getLoanProductId(loanProductJSON);
|
||||
}
|
||||
|
||||
|
||||
+26
-26
@@ -1,22 +1,25 @@
|
||||
package org.mifosplatform.integrationtests;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mifosplatform.integrationtests.common.ClientHelper;
|
||||
import org.mifosplatform.integrationtests.common.Utils;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanApplicationTestBuilder;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanProductTestBuilder;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanStatusChecker;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanTransactionHelper;
|
||||
|
||||
import com.jayway.restassured.builder.RequestSpecBuilder;
|
||||
import com.jayway.restassured.builder.ResponseSpecBuilder;
|
||||
import com.jayway.restassured.http.ContentType;
|
||||
import com.jayway.restassured.specification.RequestSpecification;
|
||||
import com.jayway.restassured.specification.ResponseSpecification;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mifosplatform.integrationtests.common.*;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanApplicationTestBuilder;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanProductTestBuilder;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanStatusChecker;
|
||||
import org.mifosplatform.integrationtests.common.loans.LoanTransactionHelper;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class LoanWithdrawnByApplicant {
|
||||
|
||||
private ResponseSpecification responseSpec;
|
||||
private RequestSpecification requestSpec;
|
||||
private LoanTransactionHelper loanTransactionHelper;
|
||||
@@ -28,32 +31,29 @@ public class LoanWithdrawnByApplicant {
|
||||
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||
responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||
|
||||
loanTransactionHelper = new LoanTransactionHelper(requestSpec,responseSpec);
|
||||
loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loanWithdrawnByApplicant(){
|
||||
Integer clientID = ClientHelper.createClient(requestSpec,responseSpec,"01 January 2012");
|
||||
public void loanWithdrawnByApplicant() {
|
||||
Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2012");
|
||||
Integer loanProductID = loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder().build());
|
||||
Integer loanID = applyForLoanApplication(clientID, loanProductID);
|
||||
Integer loanID = applyForLoanApplication(clientID, loanProductID);
|
||||
|
||||
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||
|
||||
loanTransactionHelper.withdrawLoanApplicationByClient("03 April 2012",loanID);
|
||||
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec,responseSpec,loanID);
|
||||
LoanStatusChecker.verifyLoanAccountIsNotActive(loanStatusHashMap);
|
||||
loanTransactionHelper.withdrawLoanApplicationByClient("03 April 2012", loanID);
|
||||
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
|
||||
LoanStatusChecker.verifyLoanAccountIsNotActive(loanStatusHashMap);
|
||||
|
||||
}
|
||||
|
||||
private Integer applyForLoanApplication(Integer clientID, Integer loanProductID){
|
||||
String loanApplication = new LoanApplicationTestBuilder()
|
||||
.withPrincipal("5000").withLoanTermFrequency("5").withLoanTermFrequencyAsMonths()
|
||||
.withNumberOfRepayments("5").withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsMonths()
|
||||
.withInterestRatePerPeriod("2")
|
||||
.withExpectedDisbursementDate("04 April 2012")
|
||||
.withSubmittedOnDate("02 April 2012")
|
||||
.build(clientID.toString(),loanProductID.toString());
|
||||
private Integer applyForLoanApplication(final Integer clientID, final Integer loanProductID) {
|
||||
String loanApplication = new LoanApplicationTestBuilder().withPrincipal("5000").withLoanTermFrequency("5")
|
||||
.withLoanTermFrequencyAsMonths().withNumberOfRepayments("5").withRepaymentEveryAfter("1")
|
||||
.withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod("2").withExpectedDisbursementDate("04 April 2012")
|
||||
.withSubmittedOnDate("02 April 2012").build(clientID.toString(), loanProductID.toString());
|
||||
return loanTransactionHelper.getLoanId(loanApplication);
|
||||
}
|
||||
}
|
||||
|
||||
+69
-58
@@ -1,81 +1,92 @@
|
||||
package org.mifosplatform.integrationtests.common.accounting;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.mifosplatform.integrationtests.common.ClientHelper;
|
||||
import org.mifosplatform.integrationtests.common.Utils;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.mifosplatform.integrationtests.common.Utils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class GLAccountBuilder {
|
||||
|
||||
public static final String ASSET_ACCOUNT="1";
|
||||
public static final String LIABILITY_ACCOUNT="2";
|
||||
public static final String EQUITY_ACCOUNT="3";
|
||||
public static final String INCOME_ACCOUNT="4";
|
||||
public static final String EXPENSE_ACCOUNT="5";
|
||||
public static final String ASSET_ACCOUNT = "1";
|
||||
public static final String LIABILITY_ACCOUNT = "2";
|
||||
public static final String EQUITY_ACCOUNT = "3";
|
||||
public static final String INCOME_ACCOUNT = "4";
|
||||
public static final String EXPENSE_ACCOUNT = "5";
|
||||
|
||||
private static final String ACCOUNT_USAGE_DETAIL="1";
|
||||
private static final String ACCOUNT_USAGE_HEADER="2";
|
||||
private static final String MANUAL_ENTRIES_ALLOW="true";
|
||||
private static final String MANUAL_ENTRIES_NOT_ALLOW="false";
|
||||
private static final String ACCOUNT_USAGE_DETAIL = "1";
|
||||
private static final String ACCOUNT_USAGE_HEADER = "2";
|
||||
private static final String MANUAL_ENTRIES_ALLOW = "true";
|
||||
private static final String MANUAL_ENTRIES_NOT_ALLOW = "false";
|
||||
|
||||
private static String name = Utils.randomStringGenerator("ACCOUNT_NAME_", 5);
|
||||
|
||||
private static String GLCode="";
|
||||
private static String accountType="";
|
||||
private static String accountUsage=ACCOUNT_USAGE_DETAIL;
|
||||
private static String manualEntriesAllowed=MANUAL_ENTRIES_ALLOW;
|
||||
private static String GLCode = "";
|
||||
private static String accountType = "";
|
||||
private static String accountUsage = ACCOUNT_USAGE_DETAIL;
|
||||
private static String manualEntriesAllowed = MANUAL_ENTRIES_ALLOW;
|
||||
private static String description = "DEFAULT_DESCRIPTION";
|
||||
|
||||
public String build(){
|
||||
public String build() {
|
||||
HashMap<String, String> map = new HashMap<String, String>();
|
||||
map.put("name",this.name);
|
||||
map.put("glCode",this.GLCode);
|
||||
map.put("manualEntriesAllowed",this.manualEntriesAllowed);
|
||||
map.put("type",this.accountType);
|
||||
map.put("usage",this.accountUsage);
|
||||
map.put("description",this.description);
|
||||
map.put("name", GLAccountBuilder.name);
|
||||
map.put("glCode", GLAccountBuilder.GLCode);
|
||||
map.put("manualEntriesAllowed", GLAccountBuilder.manualEntriesAllowed);
|
||||
map.put("type", GLAccountBuilder.accountType);
|
||||
map.put("usage", GLAccountBuilder.accountUsage);
|
||||
map.put("description", GLAccountBuilder.description);
|
||||
return new Gson().toJson(map);
|
||||
}
|
||||
|
||||
public GLAccountBuilder withAccountTypeAsAsset(){
|
||||
this.accountType= ASSET_ACCOUNT;
|
||||
this.GLCode= Utils.randomStringGenerator("ASSET_",2);
|
||||
this.GLCode+= Calendar.getInstance().getTimeInMillis()+""; //Added unique timestamp for avoiding random collisions
|
||||
return this;
|
||||
}
|
||||
public GLAccountBuilder withAccountTypeAsLiability(){
|
||||
this.accountType=LIABILITY_ACCOUNT;
|
||||
this.GLCode=Utils.randomStringGenerator("LIABILITY_",2);
|
||||
this.GLCode+= Calendar.getInstance().getTimeInMillis()+"";
|
||||
return this;
|
||||
}
|
||||
public GLAccountBuilder withAccountTypeAsAsEquity(){
|
||||
this.accountType=EQUITY_ACCOUNT;
|
||||
this.GLCode=Utils.randomStringGenerator("EQUITY_",2);
|
||||
this.GLCode+= Calendar.getInstance().getTimeInMillis()+"";
|
||||
return this;
|
||||
}
|
||||
public GLAccountBuilder withAccountTypeAsIncome(){
|
||||
this.accountType=INCOME_ACCOUNT;
|
||||
this.GLCode=Utils.randomStringGenerator("INCOME_",2);
|
||||
this.GLCode+= Calendar.getInstance().getTimeInMillis()+"";
|
||||
return this;
|
||||
}
|
||||
public GLAccountBuilder withAccountTypeAsExpense(){
|
||||
this.accountType=EXPENSE_ACCOUNT;
|
||||
this.GLCode=Utils.randomStringGenerator("EXPENSE_",2);
|
||||
this.GLCode+= Calendar.getInstance().getTimeInMillis()+"";
|
||||
return this;
|
||||
}
|
||||
public GLAccountBuilder withAccountUsageAsHeader(){
|
||||
this.accountUsage = ACCOUNT_USAGE_HEADER;
|
||||
public GLAccountBuilder withAccountTypeAsAsset() {
|
||||
GLAccountBuilder.accountType = ASSET_ACCOUNT;
|
||||
GLAccountBuilder.GLCode = Utils.randomStringGenerator("ASSET_", 2);
|
||||
GLAccountBuilder.GLCode += Calendar.getInstance().getTimeInMillis() + ""; // Added
|
||||
// unique
|
||||
// timestamp
|
||||
// for
|
||||
// avoiding
|
||||
// random
|
||||
// collisions
|
||||
return this;
|
||||
}
|
||||
|
||||
public GLAccountBuilder withMaualEntriesNotAllowed(){
|
||||
this.manualEntriesAllowed = MANUAL_ENTRIES_NOT_ALLOW;
|
||||
public GLAccountBuilder withAccountTypeAsLiability() {
|
||||
GLAccountBuilder.accountType = LIABILITY_ACCOUNT;
|
||||
GLAccountBuilder.GLCode = Utils.randomStringGenerator("LIABILITY_", 2);
|
||||
GLAccountBuilder.GLCode += Calendar.getInstance().getTimeInMillis() + "";
|
||||
return this;
|
||||
}
|
||||
|
||||
public GLAccountBuilder withAccountTypeAsAsEquity() {
|
||||
GLAccountBuilder.accountType = EQUITY_ACCOUNT;
|
||||
GLAccountBuilder.GLCode = Utils.randomStringGenerator("EQUITY_", 2);
|
||||
GLAccountBuilder.GLCode += Calendar.getInstance().getTimeInMillis() + "";
|
||||
return this;
|
||||
}
|
||||
|
||||
public GLAccountBuilder withAccountTypeAsIncome() {
|
||||
GLAccountBuilder.accountType = INCOME_ACCOUNT;
|
||||
GLAccountBuilder.GLCode = Utils.randomStringGenerator("INCOME_", 2);
|
||||
GLAccountBuilder.GLCode += Calendar.getInstance().getTimeInMillis() + "";
|
||||
return this;
|
||||
}
|
||||
|
||||
public GLAccountBuilder withAccountTypeAsExpense() {
|
||||
GLAccountBuilder.accountType = EXPENSE_ACCOUNT;
|
||||
GLAccountBuilder.GLCode = Utils.randomStringGenerator("EXPENSE_", 2);
|
||||
GLAccountBuilder.GLCode += Calendar.getInstance().getTimeInMillis() + "";
|
||||
return this;
|
||||
}
|
||||
|
||||
public GLAccountBuilder withAccountUsageAsHeader() {
|
||||
GLAccountBuilder.accountUsage = ACCOUNT_USAGE_HEADER;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GLAccountBuilder withMaualEntriesNotAllowed() {
|
||||
GLAccountBuilder.manualEntriesAllowed = MANUAL_ENTRIES_NOT_ALLOW;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
+19
-17
@@ -1,48 +1,50 @@
|
||||
package org.mifosplatform.integrationtests.common.accounting;
|
||||
|
||||
import com.jayway.restassured.specification.RequestSpecification;
|
||||
import com.jayway.restassured.specification.ResponseSpecification;
|
||||
import org.mifosplatform.integrationtests.common.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.mifosplatform.integrationtests.common.Utils;
|
||||
|
||||
import com.jayway.restassured.specification.RequestSpecification;
|
||||
import com.jayway.restassured.specification.ResponseSpecification;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class JournalEntryHelper {
|
||||
|
||||
private RequestSpecification requestSpec;
|
||||
private ResponseSpecification responseSpec;
|
||||
private final RequestSpecification requestSpec;
|
||||
private final ResponseSpecification responseSpec;
|
||||
|
||||
public JournalEntryHelper(RequestSpecification requestSpec, ResponseSpecification responseSpec) {
|
||||
public JournalEntryHelper(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
|
||||
this.requestSpec = requestSpec;
|
||||
this.responseSpec = responseSpec;
|
||||
}
|
||||
|
||||
public void checkJournalEntryForExpenseAccount(Account expenseAccount, String date, JournalEntry accountEntries) {
|
||||
public void checkJournalEntryForExpenseAccount(final Account expenseAccount, final String date, final JournalEntry accountEntries) {
|
||||
checkJournalEntry(expenseAccount, Utils.convertDateToURLFormat(date),accountEntries);
|
||||
}
|
||||
|
||||
|
||||
public void checkJournalEntryForAssetAccount(Account assetAccount, String date, JournalEntry... accountEntries) {
|
||||
public void checkJournalEntryForAssetAccount(final Account assetAccount, final String date, final JournalEntry... accountEntries) {
|
||||
checkJournalEntry(assetAccount,Utils.convertDateToURLFormat(date),accountEntries);
|
||||
}
|
||||
|
||||
public void checkJournalEntryForIncomeAccount(Account incomeAccount, String date, JournalEntry accountEntries) {
|
||||
public void checkJournalEntryForIncomeAccount(final Account incomeAccount, final String date, final JournalEntry accountEntries) {
|
||||
checkJournalEntry(incomeAccount, Utils.convertDateToURLFormat(date), accountEntries);
|
||||
}
|
||||
|
||||
private String getEntryValueFromJournalEntry(ArrayList<HashMap> entryResponse, int entryNumber) {
|
||||
private String getEntryValueFromJournalEntry(final ArrayList<HashMap> entryResponse, final int entryNumber) {
|
||||
HashMap map = (HashMap) entryResponse.get(entryNumber).get("entryType");
|
||||
return (String) map.get("value");
|
||||
}
|
||||
|
||||
private Float getTransactionAmountFromJournalEntry(ArrayList<HashMap> entryResponse, int entryNumber) {
|
||||
private Float getTransactionAmountFromJournalEntry(final ArrayList<HashMap> entryResponse, final int entryNumber) {
|
||||
return (Float) entryResponse.get(entryNumber).get("amount");
|
||||
}
|
||||
|
||||
private void checkJournalEntry(Account account, String date, JournalEntry... accountEntries){
|
||||
private void checkJournalEntry(final Account account, final String date, final JournalEntry... accountEntries){
|
||||
String url = createURLForGettingAccountEntries(account,date);
|
||||
ArrayList<HashMap> response = Utils.performServerGet(requestSpec, responseSpec, url, "");
|
||||
for (int i = 0; i < accountEntries.length; i++) {
|
||||
@@ -51,7 +53,7 @@ public class JournalEntryHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private String createURLForGettingAccountEntries (Account account,String date){
|
||||
private String createURLForGettingAccountEntries (final Account account,final String date){
|
||||
return new String ("/mifosng-provider/api/v1/journalentries?glAccountId=" + account.getAccountID() + "&type=" +account.getAccountType()
|
||||
+ "&fromDate=" + date + "&toDate=" + date + "&tenantIdentifier=default");
|
||||
}
|
||||
|
||||
+3
-3
@@ -12,7 +12,7 @@ public class LoanApplicationTestBuilder {
|
||||
private static final String YEARS = "3";
|
||||
private static final String DECLINING_BALANCE = "0";
|
||||
private static final String FLAT_BALANCE = "1";
|
||||
private static final String EQUAL_PRINCIPLE_PAYMENTS = "0";
|
||||
private static final String EQUAL_PRINCIPAL_PAYMENTS = "0";
|
||||
private static final String EQUAL_INSTALLMENTS = "1";
|
||||
private static final String CALCULATION_PERIOD_SAME_AS_REPAYMENT_PERIOD = "1";
|
||||
private static final String MIFOS_STANDARD_STRATEGY = "1";
|
||||
@@ -26,7 +26,7 @@ public class LoanApplicationTestBuilder {
|
||||
|
||||
private String interestRate = "2";
|
||||
private String interestType = FLAT_BALANCE;
|
||||
private String amortizationType = EQUAL_PRINCIPLE_PAYMENTS;
|
||||
private String amortizationType = EQUAL_PRINCIPAL_PAYMENTS;
|
||||
private String interestCalculationPeriodType = CALCULATION_PERIOD_SAME_AS_REPAYMENT_PERIOD;
|
||||
private final String transactionProcessingID = MIFOS_STANDARD_STRATEGY;
|
||||
private String expectedDisbursmentDate = "";
|
||||
@@ -131,7 +131,7 @@ public class LoanApplicationTestBuilder {
|
||||
}
|
||||
|
||||
public LoanApplicationTestBuilder withAmortizationTypeAsEqualPrincipalPayments() {
|
||||
this.amortizationType = EQUAL_PRINCIPLE_PAYMENTS;
|
||||
this.amortizationType = EQUAL_PRINCIPAL_PAYMENTS;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -16,7 +16,7 @@ public class LoanProductTestBuilder {
|
||||
private static final String MONTHS = "2";
|
||||
private static final String YEARS = "3";
|
||||
private static final String CALCULATION_PERIOD_SAME_AS_REPAYMENT_PERIOD="1";
|
||||
private static final String EQUAL_PRINCIPLE_PAYMENTS="0";
|
||||
private static final String EQUAL_PRINCIPAL_PAYMENTS="0";
|
||||
private static final String EQUAL_INSTALLMENTS="1";
|
||||
private static final String DECLINING_BALANCE="0";
|
||||
private static final String FLAT_BALANCE="1";
|
||||
@@ -137,8 +137,8 @@ public class LoanProductTestBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanProductTestBuilder withAmortizationTypeAsEqualPrinciplePayment(){
|
||||
this.amortizationType = EQUAL_PRINCIPLE_PAYMENTS;
|
||||
public LoanProductTestBuilder withAmortizationTypeAsEqualPrincipalPayment(){
|
||||
this.amortizationType = EQUAL_PRINCIPAL_PAYMENTS;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
+8
-6
@@ -1,20 +1,21 @@
|
||||
package org.mifosplatform.integrationtests.common.loans;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.mifosplatform.integrationtests.common.Utils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.jayway.restassured.specification.RequestSpecification;
|
||||
import com.jayway.restassured.specification.ResponseSpecification;
|
||||
import org.mifosplatform.integrationtests.common.Utils;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class LoanTransactionHelper {
|
||||
|
||||
private RequestSpecification requestSpec;
|
||||
private ResponseSpecification responseSpec;
|
||||
private final RequestSpecification requestSpec;
|
||||
private final ResponseSpecification responseSpec;
|
||||
|
||||
private static final String CREATE_LOAN_PRODUCT_URL = "/mifosng-provider/api/v1/loanproducts?tenantIdentifier=default";
|
||||
private static final String APPLY_LOAN_URL = "/mifosng-provider/api/v1/loans?tenantIdentifier=default";
|
||||
@@ -28,7 +29,7 @@ public class LoanTransactionHelper {
|
||||
private static final String WITHDRAW_LOAN_APPLICATION_COMMAND = "withdrawnByApplicant";
|
||||
|
||||
|
||||
public LoanTransactionHelper(RequestSpecification requestSpec,ResponseSpecification responseSpec){
|
||||
public LoanTransactionHelper(final RequestSpecification requestSpec,final ResponseSpecification responseSpec){
|
||||
this.requestSpec = requestSpec;
|
||||
this.responseSpec = responseSpec;
|
||||
}
|
||||
@@ -182,6 +183,7 @@ public class LoanTransactionHelper {
|
||||
return (HashMap) response.get("status");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void verifyRepaymentScheduleEntryFor(final int repaymentNumber, final float expectedPrincipalOutstanding, final Integer loanID) {
|
||||
System.out.println("---------------------------GETTING LOAN REPAYMENT SCHEDULE--------------------------------");
|
||||
ArrayList<HashMap> repaymentPeriods = getLoanRepaymentSchedule(requestSpec, responseSpec, loanID);
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createJournalEntriesForLoan(LoanDTO loanDTO) {
|
||||
public void createJournalEntriesForLoan(final LoanDTO loanDTO) {
|
||||
final GLClosure latestGLClosure = this.helper.getLatestClosureByBranch(loanDTO.getOfficeId());
|
||||
final Office office = this.helper.getOfficeById(loanDTO.getOfficeId());
|
||||
for (final LoanTransactionDTO loanTransactionDTO : loanDTO.getNewLoanTransactions()) {
|
||||
@@ -175,7 +175,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
|
||||
BigDecimal totalDebitAmount = new BigDecimal(0);
|
||||
|
||||
// handle principle payment or writeOff (and reversals)
|
||||
// handle principal payment or writeOff (and reversals)
|
||||
if (principalAmount != null && !(principalAmount.compareTo(BigDecimal.ZERO) == 0)) {
|
||||
totalDebitAmount = totalDebitAmount.add(principalAmount);
|
||||
helper.createCreditJournalEntryOrReversalForLoan(office, ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO, loanProductId, loanId,
|
||||
|
||||
+112
-150
@@ -25,7 +25,6 @@ import javax.ws.rs.core.UriInfo;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.commands.data.AuditData;
|
||||
import org.mifosplatform.commands.data.AuditSearchData;
|
||||
import org.mifosplatform.commands.data.CommandSourceData;
|
||||
import org.mifosplatform.commands.service.AuditReadPlatformService;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
|
||||
@@ -43,183 +42,146 @@ import org.springframework.stereotype.Component;
|
||||
@Scope("singleton")
|
||||
public class MakercheckersApiResource {
|
||||
|
||||
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(
|
||||
Arrays.asList("id", "actionName", "entityName", "resourceId",
|
||||
"subresourceId", "maker", "madeOnDate", "checker",
|
||||
"checkedOnDate", "processingResult", "commandAsJson",
|
||||
"officeName", "groupLevelName", "groupName", "clientName",
|
||||
"loanAccountNo", "savingsAccountNo"));
|
||||
|
||||
//Next line removed because read permissions checks part of read services
|
||||
//private final String resourceNameForPermissions = "MAKERCHECKER";
|
||||
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "actionName", "entityName", "resourceId",
|
||||
"subresourceId", "maker", "madeOnDate", "checker", "checkedOnDate", "processingResult", "commandAsJson", "officeName",
|
||||
"groupLevelName", "groupName", "clientName", "loanAccountNo", "savingsAccountNo"));
|
||||
|
||||
private final AuditReadPlatformService readPlatformService;
|
||||
private final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer;
|
||||
private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit;
|
||||
private final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final PortfolioCommandSourceWritePlatformService writePlatformService;
|
||||
private final AuditReadPlatformService readPlatformService;
|
||||
private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit;
|
||||
private final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final PortfolioCommandSourceWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public MakercheckersApiResource(
|
||||
final AuditReadPlatformService readPlatformService,
|
||||
final DefaultToApiJsonSerializer<CommandSourceData> toApiJsonSerializer,
|
||||
final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit,
|
||||
final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final PortfolioCommandSourceWritePlatformService writePlatformService) {
|
||||
this.readPlatformService = readPlatformService;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.toApiJsonSerializerAudit = toApiJsonSerializerAudit;
|
||||
this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate;
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
@Autowired
|
||||
public MakercheckersApiResource(final AuditReadPlatformService readPlatformService,
|
||||
final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializerAudit,
|
||||
final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper, final PortfolioCommandSourceWritePlatformService writePlatformService) {
|
||||
this.readPlatformService = readPlatformService;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.toApiJsonSerializerAudit = toApiJsonSerializerAudit;
|
||||
this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate;
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveCommands(@Context final UriInfo uriInfo,
|
||||
@QueryParam("actionName") final String actionName,
|
||||
@QueryParam("entityName") final String entityName,
|
||||
@QueryParam("resourceId") final Long resourceId,
|
||||
@QueryParam("makerId") final Long makerId,
|
||||
@QueryParam("makerDateTimeFrom") final String makerDateTimeFrom,
|
||||
@QueryParam("makerDateTimeTo") final String makerDateTimeTo,
|
||||
@QueryParam("officeId") final Integer officeId,
|
||||
@QueryParam("groupId") final Integer groupId,
|
||||
@QueryParam("clientId") final Integer clientId,
|
||||
@QueryParam("loanid") final Integer loanId,
|
||||
@QueryParam("savingsAccountId") final Integer savingsAccountId) {
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveCommands(@Context final UriInfo uriInfo, @QueryParam("actionName") final String actionName,
|
||||
@QueryParam("entityName") final String entityName, @QueryParam("resourceId") final Long resourceId,
|
||||
@QueryParam("makerId") final Long makerId, @QueryParam("makerDateTimeFrom") final String makerDateTimeFrom,
|
||||
@QueryParam("makerDateTimeTo") final String makerDateTimeTo, @QueryParam("officeId") final Integer officeId,
|
||||
@QueryParam("groupId") final Integer groupId, @QueryParam("clientId") final Integer clientId,
|
||||
@QueryParam("loanid") final Integer loanId, @QueryParam("savingsAccountId") final Integer savingsAccountId) {
|
||||
|
||||
final String extraCriteria = getExtraCriteria(actionName, entityName,
|
||||
resourceId, makerId, makerDateTimeFrom, makerDateTimeTo,
|
||||
officeId, groupId, clientId, loanId, savingsAccountId);
|
||||
final String extraCriteria = getExtraCriteria(actionName, entityName, resourceId, makerId, makerDateTimeFrom, makerDateTimeTo,
|
||||
officeId, groupId, clientId, loanId, savingsAccountId);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper
|
||||
.process(uriInfo.getQueryParameters());
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
final Collection<AuditData> entries = this.readPlatformService
|
||||
.retrieveAllEntriesToBeChecked(extraCriteria,
|
||||
settings.isIncludeJson());
|
||||
final Collection<AuditData> entries = this.readPlatformService.retrieveAllEntriesToBeChecked(extraCriteria,
|
||||
settings.isIncludeJson());
|
||||
|
||||
return this.toApiJsonSerializerAudit.serialize(settings, entries,
|
||||
RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
return this.toApiJsonSerializerAudit.serialize(settings, entries, RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/searchtemplate")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveAuditSearchTemplate(@Context final UriInfo uriInfo) {
|
||||
@GET
|
||||
@Path("/searchtemplate")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveAuditSearchTemplate(@Context final UriInfo uriInfo) {
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper
|
||||
.process(uriInfo.getQueryParameters());
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
final AuditSearchData auditSearchData = this.readPlatformService
|
||||
.retrieveSearchTemplate("makerchecker");
|
||||
final AuditSearchData auditSearchData = this.readPlatformService.retrieveSearchTemplate("makerchecker");
|
||||
|
||||
final Set<String> RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE = new HashSet<String>(
|
||||
Arrays.asList("appUsers", "actionNames", "entityNames"));
|
||||
final Set<String> RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE = new HashSet<String>(Arrays.asList("appUsers", "actionNames",
|
||||
"entityNames"));
|
||||
|
||||
return this.toApiJsonSerializerSearchTemplate.serialize(settings,
|
||||
auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE);
|
||||
}
|
||||
return this.toApiJsonSerializerSearchTemplate.serialize(settings, auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{auditId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String approveMakerCheckerEntry(
|
||||
@PathParam("auditId") final Long auditId,
|
||||
@QueryParam("command") final String commandParam) {
|
||||
@POST
|
||||
@Path("{auditId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String approveMakerCheckerEntry(@PathParam("auditId") final Long auditId, @QueryParam("command") final String commandParam) {
|
||||
|
||||
CommandProcessingResult result = null;
|
||||
if (is(commandParam, "approve")) {
|
||||
result = this.writePlatformService.approveEntry(auditId);
|
||||
} else {
|
||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
||||
}
|
||||
CommandProcessingResult result = null;
|
||||
if (is(commandParam, "approve")) {
|
||||
result = this.writePlatformService.approveEntry(auditId);
|
||||
} else {
|
||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
||||
}
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
return this.toApiJsonSerializerAudit.serialize(result);
|
||||
}
|
||||
|
||||
private boolean is(final String commandParam, final String commandValue) {
|
||||
return StringUtils.isNotBlank(commandParam)
|
||||
&& commandParam.trim().equalsIgnoreCase(commandValue);
|
||||
}
|
||||
private boolean is(final String commandParam, final String commandValue) {
|
||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{auditId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteMakerCheckerEntry(
|
||||
@PathParam("auditId") final Long auditId) {
|
||||
@DELETE
|
||||
@Path("{auditId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteMakerCheckerEntry(@PathParam("auditId") final Long auditId) {
|
||||
|
||||
final Long id = this.writePlatformService.deleteEntry(auditId);
|
||||
final Long id = this.writePlatformService.deleteEntry(auditId);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(CommandProcessingResult
|
||||
.commandOnlyResult(id));
|
||||
}
|
||||
return this.toApiJsonSerializerAudit.serialize(CommandProcessingResult.commandOnlyResult(id));
|
||||
}
|
||||
|
||||
private String getExtraCriteria(final String actionName,
|
||||
final String entityName, final Long resourceId, final Long makerId,
|
||||
final String makerDateTimeFrom, final String makerDateTimeTo,
|
||||
final Integer officeId, final Integer groupId,
|
||||
final Integer clientId, final Integer loanId,
|
||||
final Integer savingsAccountId) {
|
||||
private String getExtraCriteria(final String actionName, final String entityName, final Long resourceId, final Long makerId,
|
||||
final String makerDateTimeFrom, final String makerDateTimeTo, final Integer officeId, final Integer groupId,
|
||||
final Integer clientId, final Integer loanId, final Integer savingsAccountId) {
|
||||
|
||||
String extraCriteria = "";
|
||||
String extraCriteria = "";
|
||||
|
||||
if (actionName != null) {
|
||||
extraCriteria += " and aud.action_name = "
|
||||
+ ApiParameterHelper.sqlEncodeString(actionName);
|
||||
}
|
||||
if (entityName != null) {
|
||||
extraCriteria += " and aud.entity_name like "
|
||||
+ ApiParameterHelper.sqlEncodeString(entityName + "%");
|
||||
}
|
||||
if (actionName != null) {
|
||||
extraCriteria += " and aud.action_name = " + ApiParameterHelper.sqlEncodeString(actionName);
|
||||
}
|
||||
if (entityName != null) {
|
||||
extraCriteria += " and aud.entity_name like " + ApiParameterHelper.sqlEncodeString(entityName + "%");
|
||||
}
|
||||
|
||||
if (resourceId != null) {
|
||||
extraCriteria += " and aud.resource_id = " + resourceId;
|
||||
}
|
||||
if (makerId != null) {
|
||||
extraCriteria += " and aud.maker_id = " + makerId;
|
||||
}
|
||||
if (makerDateTimeFrom != null) {
|
||||
extraCriteria += " and aud.made_on_date >= "
|
||||
+ ApiParameterHelper.sqlEncodeString(makerDateTimeFrom);
|
||||
}
|
||||
if (makerDateTimeTo != null) {
|
||||
extraCriteria += " and aud.made_on_date <= "
|
||||
+ ApiParameterHelper.sqlEncodeString(makerDateTimeTo);
|
||||
}
|
||||
if (resourceId != null) {
|
||||
extraCriteria += " and aud.resource_id = " + resourceId;
|
||||
}
|
||||
if (makerId != null) {
|
||||
extraCriteria += " and aud.maker_id = " + makerId;
|
||||
}
|
||||
if (makerDateTimeFrom != null) {
|
||||
extraCriteria += " and aud.made_on_date >= " + ApiParameterHelper.sqlEncodeString(makerDateTimeFrom);
|
||||
}
|
||||
if (makerDateTimeTo != null) {
|
||||
extraCriteria += " and aud.made_on_date <= " + ApiParameterHelper.sqlEncodeString(makerDateTimeTo);
|
||||
}
|
||||
|
||||
if (officeId != null) {
|
||||
extraCriteria += " and aud.office_id = " + officeId;
|
||||
}
|
||||
if (officeId != null) {
|
||||
extraCriteria += " and aud.office_id = " + officeId;
|
||||
}
|
||||
|
||||
if (groupId != null) {
|
||||
extraCriteria += " and aud.group_id = " + groupId;
|
||||
}
|
||||
if (groupId != null) {
|
||||
extraCriteria += " and aud.group_id = " + groupId;
|
||||
}
|
||||
|
||||
if (clientId != null) {
|
||||
extraCriteria += " and aud.client_id = " + clientId;
|
||||
}
|
||||
if (clientId != null) {
|
||||
extraCriteria += " and aud.client_id = " + clientId;
|
||||
}
|
||||
|
||||
if (loanId != null) {
|
||||
extraCriteria += " and aud.loan_id = " + loanId;
|
||||
}
|
||||
if (loanId != null) {
|
||||
extraCriteria += " and aud.loan_id = " + loanId;
|
||||
}
|
||||
|
||||
if (savingsAccountId != null) {
|
||||
extraCriteria += " and aud.savings_account_id = "
|
||||
+ savingsAccountId;
|
||||
}
|
||||
if (savingsAccountId != null) {
|
||||
extraCriteria += " and aud.savings_account_id = " + savingsAccountId;
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
extraCriteria = extraCriteria.substring(4);
|
||||
}
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
extraCriteria = extraCriteria.substring(4);
|
||||
}
|
||||
|
||||
return extraCriteria;
|
||||
}
|
||||
return extraCriteria;
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -10,6 +10,7 @@ import org.joda.time.LocalDate;
|
||||
/**
|
||||
* Immutable data object representing maker-checker entry
|
||||
*/
|
||||
@Deprecated
|
||||
final public class CommandSourceData {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@@ -22,7 +23,7 @@ final public class CommandSourceData {
|
||||
private final Long entityId;
|
||||
@SuppressWarnings("unused")
|
||||
private final String entityHref;
|
||||
private String commandJson;
|
||||
private final String commandJson;
|
||||
@SuppressWarnings("unused")
|
||||
private final LocalDate madeOnDate;
|
||||
|
||||
|
||||
+4
-1
@@ -261,6 +261,10 @@ public class CommandWrapper {
|
||||
return this.entityName.equalsIgnoreCase("CLIENT");
|
||||
}
|
||||
|
||||
public boolean isClientActivation() {
|
||||
return this.actionName.equalsIgnoreCase("ACTIVATE") && this.entityName.equalsIgnoreCase("CLIENT");
|
||||
}
|
||||
|
||||
public boolean isClientIdentifierResource() {
|
||||
return this.entityName.equals("CLIENTIDENTIFIER");
|
||||
}
|
||||
@@ -483,5 +487,4 @@ public class CommandWrapper {
|
||||
public boolean isReportResource() {
|
||||
return this.entityName.equalsIgnoreCase("REPORT");
|
||||
}
|
||||
|
||||
}
|
||||
+21
-10
@@ -206,7 +206,7 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/reports/template";
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder updateReport(final Long id) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "REPORT";
|
||||
@@ -214,7 +214,7 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/reports/" + id;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder deleteReport(final Long id) {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = "REPORT";
|
||||
@@ -222,7 +222,7 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/reports/" + id;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder updateCurrencies() {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "CURRENCY";
|
||||
@@ -328,10 +328,20 @@ public class CommandWrapperBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder activateClient(final Long clientId) {
|
||||
this.actionName = "ACTIVATE";
|
||||
this.entityName = "CLIENT";
|
||||
this.entityId = clientId;
|
||||
this.clientId = clientId;
|
||||
this.href = "/clients/" + clientId + "?command=activate&template=true";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateClient(final Long clientId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "CLIENT";
|
||||
this.entityId = clientId;
|
||||
this.clientId = clientId;
|
||||
this.href = "/clients/" + clientId;
|
||||
return this;
|
||||
}
|
||||
@@ -340,6 +350,7 @@ public class CommandWrapperBuilder {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = "CLIENT";
|
||||
this.entityId = clientId;
|
||||
this.clientId = clientId;
|
||||
this.href = "/clients/" + clientId;
|
||||
this.json = "{}";
|
||||
return this;
|
||||
@@ -868,7 +879,7 @@ public class CommandWrapperBuilder {
|
||||
this.loanId = loanId;
|
||||
this.href = "/loans/" + loanId + "/collaterals/" + collateralId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateCollectionSheet(final Long groupId) {
|
||||
this.actionName = "UPDATE";
|
||||
@@ -878,26 +889,26 @@ public class CommandWrapperBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder createCenter() {
|
||||
public CommandWrapperBuilder createCenter() {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "CENTER";
|
||||
this.href = "/centers/template";
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateCenter(Long centerId) {
|
||||
public CommandWrapperBuilder updateCenter(final Long centerId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "CENTER";
|
||||
this.entityId = centerId;
|
||||
this.href = "/centers/" + centerId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder deleteCenter(Long centerId) {
|
||||
public CommandWrapperBuilder deleteCenter(final Long centerId) {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = "CENTER";
|
||||
this.entityId = centerId;
|
||||
this.href = "/centers/" + centerId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.commands.service;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.commands.data.CommandSourceData;
|
||||
|
||||
public interface PortfolioCommandsReadPlatformService {
|
||||
|
||||
CommandSourceData retrieveById(Long id);
|
||||
|
||||
Collection<CommandSourceData> retrieveUnprocessChangesByEntityNameAndId(String entityName, Long entityId);
|
||||
}
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.commands.service;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.commands.data.CommandSourceData;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class PortfolioCommandsReadPlatformServiceImpl implements PortfolioCommandsReadPlatformService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Autowired
|
||||
public PortfolioCommandsReadPlatformServiceImpl(final TenantAwareRoutingDataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
private static final class CommandSourceMapper implements RowMapper<CommandSourceData> {
|
||||
|
||||
public String schema() {
|
||||
return " mc.id as id, mc.action_name as actionName, mc.entity_name as entityName, mc.resource_id as entityId, mc.api_get_url as getHref, "
|
||||
+ "mc.command_as_json as taskJson, mc.made_on_date as madeOnDate from m_portfolio_command_source mc ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandSourceData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long id = rs.getLong("id");
|
||||
final String actionName = rs.getString("actionName");
|
||||
final String entityName = rs.getString("entityName");
|
||||
final Long entityId = JdbcSupport.getLong(rs, "entityId");
|
||||
final String taskJson = rs.getString("taskJson");
|
||||
final String getHref = rs.getString("getHref");
|
||||
final LocalDate madeOnDate = JdbcSupport.getLocalDate(rs, "madeOnDate");
|
||||
|
||||
return new CommandSourceData(id, actionName, entityName, entityId, getHref, taskJson, madeOnDate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandSourceData retrieveById(final Long id) {
|
||||
|
||||
final CommandSourceMapper rm = new CommandSourceMapper();
|
||||
final String sql = "select " + rm.schema() + " where mc.id=?";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { id });
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<CommandSourceData> retrieveUnprocessChangesByEntityNameAndId(final String entityName, final Long entityId) {
|
||||
|
||||
final CommandSourceMapper rm = new CommandSourceMapper();
|
||||
final String sql = "select "
|
||||
+ rm.schema()
|
||||
+ " where mc.entity_name like ? and mc.resource_id = ? and mc.checker_id is null and mc.processing_result_enum = 2 order by mc.made_on_date DESC, mc.action_name ASC";
|
||||
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { entityName, entityId });
|
||||
}
|
||||
}
|
||||
+4
@@ -149,6 +149,10 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
handler = applicationContext.getBean("updateClientCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isDelete()) {
|
||||
handler = applicationContext.getBean("deleteClientCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isClientActivation()) {
|
||||
handler = applicationContext.getBean("activateClientCommandHandler", NewCommandSourceHandler.class);
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
// end of client
|
||||
} else if (wrapper.isUpdateRolePermissions()) {
|
||||
|
||||
+2
-1
@@ -9,4 +9,5 @@ public interface ConfigurationDomainService {
|
||||
|
||||
boolean isMakerCheckerEnabledForTask(String taskPermissionCode);
|
||||
|
||||
}
|
||||
boolean isClientPendingApprovalAllowedEnabled();
|
||||
}
|
||||
+9
@@ -39,4 +39,13 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
|
||||
|
||||
return thisTask.hasMakerCheckerEnabled() && property.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClientPendingApprovalAllowedEnabled() {
|
||||
final String propertyKey = "allow-pending-client-status";
|
||||
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByName(propertyKey);
|
||||
if (property == null) { throw new GlobalConfigurationPropertyNotFoundException(propertyKey); }
|
||||
|
||||
return property.isEnabled();
|
||||
}
|
||||
}
|
||||
+2
-6
@@ -35,12 +35,10 @@ public class ApiRequestParameterHelper {
|
||||
}
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(queryParameters);
|
||||
final boolean template = ApiParameterHelper.template(queryParameters);
|
||||
final Long commandId = ApiParameterHelper.commandId(queryParameters);
|
||||
final boolean makerCheckerable = ApiParameterHelper.makerCheckerable(queryParameters);
|
||||
final boolean includeJson = ApiParameterHelper.includeJson(queryParameters);
|
||||
|
||||
return ApiRequestJsonSerializationSettings
|
||||
.from(prettyPrint, responseParameters, template, commandId, makerCheckerable, includeJson);
|
||||
return ApiRequestJsonSerializationSettings.from(prettyPrint, responseParameters, template, makerCheckerable, includeJson);
|
||||
}
|
||||
|
||||
public ApiRequestJsonSerializationSettings process(final MultivaluedMap<String, String> queryParameters) {
|
||||
@@ -48,11 +46,9 @@ public class ApiRequestParameterHelper {
|
||||
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(queryParameters);
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(queryParameters);
|
||||
final boolean template = ApiParameterHelper.template(queryParameters);
|
||||
final Long commandId = ApiParameterHelper.commandId(queryParameters);
|
||||
final boolean makerCheckerable = ApiParameterHelper.makerCheckerable(queryParameters);
|
||||
final boolean includeJson = ApiParameterHelper.includeJson(queryParameters);
|
||||
|
||||
return ApiRequestJsonSerializationSettings
|
||||
.from(prettyPrint, responseParameters, template, commandId, makerCheckerable, includeJson);
|
||||
return ApiRequestJsonSerializationSettings.from(prettyPrint, responseParameters, template, makerCheckerable, includeJson);
|
||||
}
|
||||
}
|
||||
+10
-1
@@ -75,6 +75,15 @@ public class DataValidatorBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void failWithCode(final String errorCode) {
|
||||
StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(resource).append(".").append(this.parameter)
|
||||
.append(errorCode);
|
||||
StringBuilder defaultEnglishMessage = new StringBuilder("Failed data validation due to: ").append(errorCode).append(".");
|
||||
ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(),
|
||||
this.parameter, this.value);
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
public DataValidatorBuilder equalToParameter(final String linkedParameterName, final Object linkedValue) {
|
||||
if (value == null && linkedValue == null && ignoreNullValue) { return this; }
|
||||
|
||||
@@ -523,5 +532,5 @@ public class DataValidatorBuilder {
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-14
@@ -16,28 +16,25 @@ public class ApiRequestJsonSerializationSettings {
|
||||
private final boolean prettyPrint;
|
||||
private final Set<String> parametersForPartialResponse;
|
||||
private final boolean template;
|
||||
private final Long commandId;
|
||||
private final boolean makerCheckerable;
|
||||
private final boolean includeJson;
|
||||
|
||||
public ApiRequestJsonSerializationSettings(final boolean prettyPrint, final Set<String> parametersForPartialResponse,
|
||||
final boolean template, final Long commandId, final boolean makerCheckerable, final boolean includeJson) {
|
||||
final boolean template, final boolean makerCheckerable, final boolean includeJson) {
|
||||
this.prettyPrint = prettyPrint;
|
||||
this.parametersForPartialResponse = parametersForPartialResponse;
|
||||
this.template = template;
|
||||
this.commandId = commandId;
|
||||
this.makerCheckerable = makerCheckerable;
|
||||
this.includeJson = includeJson;
|
||||
}
|
||||
|
||||
public static ApiRequestJsonSerializationSettings from(final boolean prettyPrint, final Set<String> parametersForPartialResponse,
|
||||
final boolean template, final Long commandId, final boolean makerCheckerable, final boolean includeJson) {
|
||||
final boolean template, final boolean makerCheckerable, final boolean includeJson) {
|
||||
|
||||
// FIXME - KW - rather than always creating new objects for this could
|
||||
// just send by common ones like, prettyprint=false, empty response
|
||||
// parameters
|
||||
return new ApiRequestJsonSerializationSettings(prettyPrint, parametersForPartialResponse, template, commandId, makerCheckerable,
|
||||
includeJson);
|
||||
return new ApiRequestJsonSerializationSettings(prettyPrint, parametersForPartialResponse, template, makerCheckerable, includeJson);
|
||||
}
|
||||
|
||||
public boolean isPrettyPrint() {
|
||||
@@ -56,10 +53,6 @@ public class ApiRequestJsonSerializationSettings {
|
||||
return this.includeJson;
|
||||
}
|
||||
|
||||
public Long getCommandId() {
|
||||
return this.commandId;
|
||||
}
|
||||
|
||||
public Set<String> getParametersForPartialResponse() {
|
||||
return this.parametersForPartialResponse;
|
||||
}
|
||||
@@ -67,8 +60,4 @@ public class ApiRequestJsonSerializationSettings {
|
||||
public boolean isPartialResponseRequired() {
|
||||
return !this.parametersForPartialResponse.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isCommandIdPassed() {
|
||||
return this.commandId != null;
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -8,13 +8,14 @@ package org.mifosplatform.organisation.office.data;
|
||||
/**
|
||||
* Immutable data object used for office lookups (will remove eventually and just use {@link OfficeData}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class OfficeLookup {
|
||||
|
||||
private Long id;
|
||||
private final Long id;
|
||||
@SuppressWarnings("unused")
|
||||
private String name;
|
||||
private final String name;
|
||||
@SuppressWarnings("unused")
|
||||
private String nameDecorated;
|
||||
private final String nameDecorated;
|
||||
|
||||
public OfficeLookup(final Long id, final String name, final String nameDecorated) {
|
||||
this.id = id;
|
||||
|
||||
+1
@@ -21,6 +21,7 @@ public interface OfficeReadPlatformService {
|
||||
* Deprecated so cane eventually remove need for OfficeLookup type - so use
|
||||
* retrieveAllOfficesForDropdown instead.
|
||||
*/
|
||||
@Deprecated
|
||||
Collection<OfficeLookup> retrieveAllOfficesForLookup();
|
||||
|
||||
OfficeData retrieveOffice(Long officeId);
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package org.mifosplatform.portfolio.client.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||
|
||||
public class ClientApiConstants {
|
||||
|
||||
public static final String CLIENT_RESOURCE_NAME = "client";
|
||||
|
||||
// general
|
||||
public static final String localeParamName = "locale";
|
||||
public static final String dateFormatParamName = "dateFormat";
|
||||
|
||||
// request parameters
|
||||
public static final String idParamName = "id";
|
||||
public static final String groupIdParamName = "groupId";
|
||||
public static final String accountNoParamName = "accountNo";
|
||||
public static final String externalIdParamName = "externalId";
|
||||
public static final String firstnameParamName = "firstname";
|
||||
public static final String middlenameParamName = "middlename";
|
||||
public static final String lastnameParamName = "lastname";
|
||||
public static final String fullnameParamName = "fullname";
|
||||
public static final String officeIdParamName = "officeId";
|
||||
public static final String staffIdParamName = "staffId";
|
||||
public static final String activeParamName = "active";
|
||||
public static final String activationDateParamName = "activationDate";
|
||||
|
||||
// response parameters
|
||||
public static final String statusParamName = "status";
|
||||
public static final String hierarchyParamName = "hierarchy";
|
||||
public static final String displayNameParamName = "displayName";
|
||||
public static final String officeNameParamName = "officeName";
|
||||
public static final String staffNameParamName = "staffName";
|
||||
public static final String imageKeyParamName = "imageKey";
|
||||
public static final String imagePresentParamName = "imagePresent";
|
||||
|
||||
// associations related part of response
|
||||
public static final String parentGroupsParamName = "groups";
|
||||
|
||||
// template related part of response
|
||||
public static final String officeOptionsParamName = "officeOptions";
|
||||
public static final String staffOptionsParamName = "staffOptions";
|
||||
|
||||
public static final Set<String> CLIENT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
dateFormatParamName, groupIdParamName, accountNoParamName, externalIdParamName, firstnameParamName, middlenameParamName,
|
||||
lastnameParamName, fullnameParamName, officeIdParamName, staffIdParamName, activeParamName, activationDateParamName));
|
||||
|
||||
/**
|
||||
* These parameters will match the class level parameters of
|
||||
* {@link ClientData}. Where possible, we try to get response parameters to
|
||||
* match those of request parameters.
|
||||
*/
|
||||
public static final Set<String> CLIENT_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName, accountNoParamName,
|
||||
externalIdParamName, statusParamName, firstnameParamName, middlenameParamName, lastnameParamName, fullnameParamName,
|
||||
displayNameParamName, officeIdParamName, officeNameParamName, staffIdParamName, staffNameParamName, hierarchyParamName,
|
||||
officeOptionsParamName, staffOptionsParamName));
|
||||
|
||||
public static final Set<String> ACTIVATION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
dateFormatParamName, activationDateParamName));
|
||||
}
|
||||
+2
-2
@@ -111,7 +111,7 @@ public class ClientImagesApiResource {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
||||
|
||||
final ClientData clientData = this.clientReadPlatformService.retrieveIndividualClient(clientId);
|
||||
final ClientData clientData = this.clientReadPlatformService.retrieveOne(clientId);
|
||||
|
||||
if (clientData.imageKeyDoesNotExist()) { throw new ImageNotFoundException("clients", clientId); }
|
||||
|
||||
@@ -134,7 +134,7 @@ public class ClientImagesApiResource {
|
||||
public Response downloadClientImage(@PathParam("clientId") final Long clientId) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
||||
final ClientData clientData = this.clientReadPlatformService.retrieveIndividualClient(clientId);
|
||||
final ClientData clientData = this.clientReadPlatformService.retrieveOne(clientId);
|
||||
|
||||
if (clientData.imageKeyDoesNotExist()) { throw new ImageNotFoundException("clients", clientId); }
|
||||
|
||||
|
||||
+78
-159
@@ -26,24 +26,21 @@ import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.commands.data.CommandSourceData;
|
||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||
import org.mifosplatform.commands.service.CommandWrapperBuilder;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandsReadPlatformService;
|
||||
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;
|
||||
import org.mifosplatform.organisation.office.data.OfficeLookup;
|
||||
import org.mifosplatform.organisation.office.data.OfficeData;
|
||||
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
|
||||
import org.mifosplatform.portfolio.client.command.ClientCommand;
|
||||
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData;
|
||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||
import org.mifosplatform.portfolio.client.serialization.ClientCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
||||
import org.mifosplatform.portfolio.group.service.SearchParameters;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -53,185 +50,84 @@ import org.springframework.stereotype.Component;
|
||||
@Scope("singleton")
|
||||
public class ClientsApiResource {
|
||||
|
||||
private final Set<String> CLIENT_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "accountNo", "externalId", "firstname",
|
||||
"middlename", "lastname", "fullname", "displayName", "officeId", "officeName", "joinedDate", "imageKey", "imagePresent",
|
||||
"parentGroups", "allowedOffices", "currentChange", "allChanges"));
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final ClientReadPlatformService clientReadPlatformService;
|
||||
private final OfficeReadPlatformService officeReadPlatformService;
|
||||
private final ToApiJsonSerializer<ClientData> toApiJsonSerializer;
|
||||
private final ToApiJsonSerializer<ClientAccountSummaryCollectionData> clientAccountSummaryToApiJsonSerializer;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final PortfolioCommandsReadPlatformService commandSourceReadPlatformService;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
private final ClientCommandFromApiJsonDeserializer clientCommandFromApiJsonDeserializer;
|
||||
|
||||
@Autowired
|
||||
public ClientsApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService,
|
||||
final OfficeReadPlatformService officeReadPlatformService, final ToApiJsonSerializer<ClientData> toApiJsonSerializer,
|
||||
final ClientCommandFromApiJsonDeserializer clientCommandFromApiJsonDeserializer,
|
||||
final ToApiJsonSerializer<ClientAccountSummaryCollectionData> clientAccountSummaryToApiJsonSerializer,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final PortfolioCommandsReadPlatformService commandsReadPlatformService,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||
this.context = context;
|
||||
this.clientReadPlatformService = readPlatformService;
|
||||
this.officeReadPlatformService = officeReadPlatformService;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.clientCommandFromApiJsonDeserializer = clientCommandFromApiJsonDeserializer;
|
||||
this.clientAccountSummaryToApiJsonSerializer = clientAccountSummaryToApiJsonSerializer;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.commandSourceReadPlatformService = commandsReadPlatformService;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveAllIndividualClients(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch,
|
||||
@QueryParam("officeId") final Long officeId, @QueryParam("externalId") final String externalId,
|
||||
@QueryParam("displayName") final String displayName, @QueryParam("firstName") final String firstName,
|
||||
@QueryParam("lastName") final String lastName, @QueryParam("underHierarchy") final String hierarchy) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("CLIENT");
|
||||
|
||||
// FIXME - kw - rather than exposing SQL through the api can we not just
|
||||
// pass parameter we want to search by and build up sql like is done for
|
||||
// other parameters?
|
||||
final String extraCriteria = buildSqlStringFromClientCriteria(sqlSearch, officeId, externalId, displayName, firstName, lastName,
|
||||
hierarchy);
|
||||
|
||||
final Collection<ClientData> clients = this.clientReadPlatformService.retrieveAllIndividualClients(extraCriteria);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, clients, CLIENT_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
private String buildSqlStringFromClientCriteria(final String sqlSearch, final Long officeId, final String externalId,
|
||||
final String displayName, final String firstName, final String lastName, final String hierarchy) {
|
||||
|
||||
String extraCriteria = "";
|
||||
|
||||
if (sqlSearch != null) {
|
||||
extraCriteria = " and (" + sqlSearch + ")";
|
||||
}
|
||||
|
||||
if (officeId != null) {
|
||||
extraCriteria += " and office_id = " + officeId;
|
||||
}
|
||||
|
||||
if (externalId != null) {
|
||||
extraCriteria += " and external_id like " + ApiParameterHelper.sqlEncodeString(externalId);
|
||||
}
|
||||
|
||||
if (displayName != null) {
|
||||
extraCriteria += " and concat(ifnull(firstname, ''), if(firstname > '',' ', '') , ifnull(lastname, '')) like "
|
||||
+ ApiParameterHelper.sqlEncodeString(displayName);
|
||||
}
|
||||
|
||||
if (firstName != null) {
|
||||
extraCriteria += " and firstname like " + ApiParameterHelper.sqlEncodeString(firstName);
|
||||
}
|
||||
|
||||
if (lastName != null) {
|
||||
extraCriteria += " and lastname like " + ApiParameterHelper.sqlEncodeString(lastName);
|
||||
}
|
||||
|
||||
if (hierarchy != null) {
|
||||
extraCriteria += " and o.hierarchy like " + ApiParameterHelper.sqlEncodeString(hierarchy + "%");
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
extraCriteria = extraCriteria.substring(4);
|
||||
}
|
||||
|
||||
return extraCriteria;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{clientId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveClient(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("CLIENT");
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
ClientData clientData = this.clientReadPlatformService.retrieveIndividualClient(clientId);
|
||||
if (settings.isTemplate()) {
|
||||
// FIXME - KW - no need for special OfficeLookup object, just use
|
||||
// OfficeData and only populate with id, name, nameDecorated
|
||||
final List<OfficeLookup> allowedOffices = new ArrayList<OfficeLookup>(officeReadPlatformService.retrieveAllOfficesForLookup());
|
||||
clientData = ClientData.templateOnTop(clientData, allowedOffices);
|
||||
}
|
||||
if (settings.isCommandIdPassed()) {
|
||||
clientData = handleRequestToIntegrateProposedChangesFromCommand(clientId, settings.getCommandId(), clientData);
|
||||
}
|
||||
|
||||
// pick up possibility of changes by default - might push down a layer
|
||||
// into the retrieve client method
|
||||
final Collection<ClientData> dataChanges = retrieveAllUnprocessedDataChanges(clientId);
|
||||
clientData = ClientData.integrateChanges(clientData, clientData.currentChange(), dataChanges);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(settings, clientData, CLIENT_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
private ClientData handleRequestToIntegrateProposedChangesFromCommand(final Long clientId, final Long commandId,
|
||||
final ClientData clientData) {
|
||||
final CommandSourceData entry = this.commandSourceReadPlatformService.retrieveById(commandId);
|
||||
|
||||
final ClientCommand command = this.clientCommandFromApiJsonDeserializer.commandFromApiJson(entry.json());
|
||||
final ClientData currentChange = ClientData.dataChangeInstance(clientId, command.getOfficeId(), command.getExternalId(),
|
||||
command.getFirstname(), command.getMiddlename(), command.getLastname(), command.getFullname(), command.getJoiningDate());
|
||||
|
||||
final Collection<ClientData> dataChanges = null; // retrieveAllUnprocessedDataChanges(clientId);
|
||||
return ClientData.integrateChanges(clientData, currentChange, dataChanges);
|
||||
}
|
||||
|
||||
private Collection<ClientData> retrieveAllUnprocessedDataChanges(final Long clientId) {
|
||||
Collection<ClientData> dataChanges = new ArrayList<ClientData>();
|
||||
|
||||
Collection<CommandSourceData> unprocessedChanges = this.commandSourceReadPlatformService.retrieveUnprocessChangesByEntityNameAndId(
|
||||
"CLIENT", clientId);
|
||||
for (CommandSourceData commandSourceData : unprocessedChanges) {
|
||||
final ClientCommand command = this.clientCommandFromApiJsonDeserializer.commandFromApiJson(commandSourceData.json());
|
||||
final ClientData change = ClientData
|
||||
.dataChangeInstance(clientId, command.getOfficeId(), command.getExternalId(), command.getFirstname(),
|
||||
command.getMiddlename(), command.getLastname(), command.getFullname(), command.getJoiningDate());
|
||||
dataChanges.add(change);
|
||||
}
|
||||
|
||||
if (dataChanges.isEmpty()) {
|
||||
dataChanges = null;
|
||||
}
|
||||
|
||||
return dataChanges;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String newClientDetails(@Context final UriInfo uriInfo) {
|
||||
public String retrieveTemplate(@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("CLIENT");
|
||||
context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
|
||||
final ClientData clientData = this.clientReadPlatformService.retrieveTemplate();
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, clientData, ClientApiConstants.CLIENT_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveAll(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch,
|
||||
@QueryParam("officeId") final Long officeId, @QueryParam("externalId") final String externalId,
|
||||
@QueryParam("displayName") final String displayName, @QueryParam("firstName") final String firstname,
|
||||
@QueryParam("lastName") final String lastname, @QueryParam("underHierarchy") final String hierarchy) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
|
||||
final SearchParameters searchParameters = SearchParameters.forClients(sqlSearch, officeId, externalId, displayName, firstname,
|
||||
lastname, hierarchy);
|
||||
final Collection<ClientData> clients = this.clientReadPlatformService.retrieveAll(searchParameters);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, clients, ClientApiConstants.CLIENT_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{clientId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveOne(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
ClientData clientData = this.clientReadPlatformService.retrieveNewClientDetails();
|
||||
if (settings.isCommandIdPassed()) {
|
||||
clientData = handleRequestToIntegrateProposedChangesFromCommand(null, settings.getCommandId(), clientData);
|
||||
ClientData clientData = this.clientReadPlatformService.retrieveOne(clientId);
|
||||
if (settings.isTemplate()) {
|
||||
final List<OfficeData> allowedOffices = new ArrayList<OfficeData>(officeReadPlatformService.retrieveAllOfficesForDropdown());
|
||||
clientData = ClientData.templateOnTop(clientData, allowedOffices);
|
||||
}
|
||||
|
||||
return this.toApiJsonSerializer.serialize(settings, clientData, CLIENT_DATA_PARAMETERS);
|
||||
return this.toApiJsonSerializer.serialize(settings, clientData, ClientApiConstants.CLIENT_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String createClient(final String apiRequestBodyAsJson) {
|
||||
public String create(final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
|
||||
.createClient() //
|
||||
@@ -247,7 +143,7 @@ public class ClientsApiResource {
|
||||
@Path("{clientId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateClient(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) {
|
||||
public String update(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
|
||||
.updateClient(clientId) //
|
||||
@@ -263,7 +159,7 @@ public class ClientsApiResource {
|
||||
@Path("{clientId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteClient(@PathParam("clientId") final Long clientId) {
|
||||
public String delete(@PathParam("clientId") final Long clientId) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
|
||||
.deleteClient(clientId) //
|
||||
@@ -274,26 +170,49 @@ public class ClientsApiResource {
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{clientId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String activate(@PathParam("clientId") final Long clientId, @QueryParam("command") final String commandParam,
|
||||
final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||
|
||||
CommandProcessingResult result = null;
|
||||
if (is(commandParam, "activate")) {
|
||||
final CommandWrapper commandRequest = builder.activateClient(clientId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
//
|
||||
throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "activate" });
|
||||
}
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
private boolean is(final String commandParam, final String commandValue) {
|
||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{clientId}/loans")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveClientAccounts(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) {
|
||||
public String retrieveAssociatedAccounts(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("CLIENT");
|
||||
context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
|
||||
final ClientAccountSummaryCollectionData clientAccount = this.clientReadPlatformService.retrieveClientAccountDetails(clientId);
|
||||
|
||||
final Set<String> CLIENT_ACCOUNTS_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("pendingApprovalLoans",
|
||||
"awaitingDisbursalLoans", "openLoans", "closedLoans", "anyLoanCount", "pendingApprovalLoanCount",
|
||||
"awaitingDisbursalLoanCount", "activeLoanCount", "closedLoanCount", "pendingApprovalDepositAccountsCount",
|
||||
"pendingApprovalDepositAccounts", "approvedDepositAccountsCount", "approvedDepositAccounts",
|
||||
"withdrawnByClientDepositAccountsCount", "withdrawnByClientDepositAccounts", "closedDepositAccountsCount",
|
||||
"closedDepositAccounts", "maturedDepositAccountsCount", "maturedDepositAccounts", "rejectedDepositAccountsCount",
|
||||
"rejectedDepositAccounts", "preclosedDepositAccountsCount", "preclosedDepositAccounts",
|
||||
"pendingApprovalSavingAccountsCount", "pendingApprovalSavingAccounts", "approvedSavingAccountsCount",
|
||||
"approvedSavingAccounts", "withdrawnByClientSavingAccountsCount", "withdrawnByClientSavingAccounts",
|
||||
"rejectedSavingAccountsCount", "rejectedSavingAccounts", "closedSavingAccountsCount", "closedSavingAccounts"));
|
||||
"awaitingDisbursalLoanCount", "activeLoanCount", "closedLoanCount", "pendingApprovalSavingAccountsCount",
|
||||
"pendingApprovalSavingAccounts", "approvedSavingAccountsCount", "approvedSavingAccounts",
|
||||
"withdrawnByClientSavingAccountsCount", "withdrawnByClientSavingAccounts", "rejectedSavingAccountsCount",
|
||||
"rejectedSavingAccounts", "closedSavingAccountsCount", "closedSavingAccounts"));
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.clientAccountSummaryToApiJsonSerializer.serialize(settings, clientAccount, CLIENT_ACCOUNTS_DATA_PARAMETERS);
|
||||
|
||||
+74
-88
@@ -13,7 +13,8 @@ import org.apache.commons.lang.builder.CompareToBuilder;
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.organisation.office.data.OfficeLookup;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.organisation.office.data.OfficeData;
|
||||
import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
||||
|
||||
/**
|
||||
@@ -24,78 +25,70 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
private final Long id;
|
||||
private final String accountNo;
|
||||
private final String externalId;
|
||||
|
||||
private final EnumOptionData status;
|
||||
private final LocalDate activationDate;
|
||||
|
||||
private final String firstname;
|
||||
private final String middlename;
|
||||
private final String lastname;
|
||||
private final String fullname;
|
||||
private final String displayName;
|
||||
|
||||
private final Long officeId;
|
||||
private final String officeName;
|
||||
private final LocalDate joinedDate;
|
||||
|
||||
private final String imageKey;
|
||||
@SuppressWarnings("unused")
|
||||
private final Boolean imagePresent;
|
||||
|
||||
private final Boolean clientPendingApprovalAllowed;
|
||||
|
||||
// associations
|
||||
private final Collection<GroupGeneralData> parentGroups;
|
||||
private final Collection<GroupGeneralData> groups;
|
||||
|
||||
// template
|
||||
private final List<OfficeLookup> allowedOffices;
|
||||
private final ClientData currentChange;
|
||||
private final Collection<ClientData> allChanges;
|
||||
private final Collection<OfficeData> officeOptions;
|
||||
|
||||
public static ClientData dataChangeInstance(final Long id, final Long officeId, final String externalId, final String firstname,
|
||||
final String middlename, final String lastname, final String fullname, final LocalDate joiningDate) {
|
||||
|
||||
String localDisplayName = null;
|
||||
return new ClientData(null, officeId, null, id, firstname, middlename, lastname, fullname, localDisplayName, externalId,
|
||||
joiningDate, null, null, null, null, null);
|
||||
public static ClientData template(final Long officeId, final LocalDate joinedDate, final Boolean clientPendingApprovalAllowed,
|
||||
final Collection<OfficeData> allowedOffices) {
|
||||
return new ClientData(null, null, officeId, null, null, null, null, null, null, null, null, joinedDate, null,
|
||||
clientPendingApprovalAllowed, allowedOffices, null);
|
||||
}
|
||||
|
||||
public static ClientData integrateChanges(final ClientData clientData, final ClientData currentChange,
|
||||
final Collection<ClientData> allChanges) {
|
||||
return new ClientData(clientData.accountNo, clientData.officeId, clientData.officeName, clientData.id, clientData.firstname,
|
||||
clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName, clientData.externalId,
|
||||
clientData.joinedDate, clientData.imageKey, clientData.allowedOffices, currentChange, allChanges, clientData.parentGroups);
|
||||
}
|
||||
public static ClientData templateOnTop(final ClientData clientData, final List<OfficeData> allowedOffices) {
|
||||
|
||||
public static ClientData template(final Long officeId, final LocalDate joinedDate, final List<OfficeLookup> allowedOffices) {
|
||||
return new ClientData(null, officeId, null, null, null, null, null, null, null, null, joinedDate, null, allowedOffices, null, null,
|
||||
null);
|
||||
}
|
||||
|
||||
public static ClientData templateOnTop(final ClientData clientData, final List<OfficeLookup> allowedOffices) {
|
||||
|
||||
return new ClientData(clientData.accountNo, clientData.officeId, clientData.officeName, clientData.id, clientData.firstname,
|
||||
clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName, clientData.externalId,
|
||||
clientData.joinedDate, clientData.imageKey, allowedOffices, clientData.currentChange, clientData.allChanges,
|
||||
clientData.parentGroups);
|
||||
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id,
|
||||
clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName,
|
||||
clientData.externalId, clientData.activationDate, clientData.imageKey, clientData.clientPendingApprovalAllowed,
|
||||
allowedOffices, clientData.groups);
|
||||
}
|
||||
|
||||
public static ClientData setParentGroups(final ClientData clientData, final Collection<GroupGeneralData> parentGroups) {
|
||||
return new ClientData(clientData.accountNo, clientData.officeId, clientData.officeName, clientData.id, clientData.firstname,
|
||||
clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName, clientData.externalId,
|
||||
clientData.joinedDate, clientData.imageKey, clientData.allowedOffices, clientData.currentChange, clientData.allChanges,
|
||||
parentGroups);
|
||||
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id,
|
||||
clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName,
|
||||
clientData.externalId, clientData.activationDate, clientData.imageKey, clientData.clientPendingApprovalAllowed,
|
||||
clientData.officeOptions, parentGroups);
|
||||
}
|
||||
|
||||
public static ClientData clientIdentifier(final Long id, final String accountIdentifier, final String firstname,
|
||||
public static ClientData clientIdentifier(final Long id, final String accountNo, final EnumOptionData status, final String firstname,
|
||||
final String middlename, final String lastname, final String fullname, final String displayName, final Long officeId,
|
||||
final String officeName) {
|
||||
|
||||
return new ClientData(accountIdentifier, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, null,
|
||||
null, null, null, null, null, null);
|
||||
return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, null,
|
||||
null, null, null, null, null);
|
||||
}
|
||||
|
||||
public static ClientData lookup(final Long id, final String displayName, final Long officeId, final String officeName) {
|
||||
return new ClientData(null, officeId, officeName, id, null, null, null, null, displayName, null, null, null, null, null, null, null);
|
||||
return new ClientData(null, null, officeId, officeName, id, null, null, null, null, displayName, null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
public ClientData(final String accountNo, final Long officeId, final String officeName, final Long id, final String firstname,
|
||||
final String middlename, final String lastname, final String fullname, final String displayName, final String externalId,
|
||||
final LocalDate joinedDate, final String imageKey, final List<OfficeLookup> allowedOffices, final ClientData currentChange,
|
||||
final Collection<ClientData> allChanges, final Collection<GroupGeneralData> parentGroups) {
|
||||
public ClientData(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName, final Long id,
|
||||
final String firstname, final String middlename, final String lastname, final String fullname, final String displayName,
|
||||
final String externalId, final LocalDate activationDate, final String imageKey, final Boolean clientPendingApprovalAllowed,
|
||||
final Collection<OfficeData> allowedOffices, final Collection<GroupGeneralData> groups) {
|
||||
this.accountNo = accountNo;
|
||||
this.status = status;
|
||||
this.officeId = officeId;
|
||||
this.officeName = officeName;
|
||||
this.id = id;
|
||||
@@ -105,17 +98,49 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
this.fullname = StringUtils.defaultIfEmpty(fullname, null);
|
||||
this.displayName = StringUtils.defaultIfEmpty(displayName, null);
|
||||
this.externalId = StringUtils.defaultIfEmpty(externalId, null);
|
||||
this.joinedDate = joinedDate;
|
||||
this.activationDate = activationDate;
|
||||
this.imageKey = imageKey;
|
||||
if (imageKey != null) {
|
||||
this.imagePresent = Boolean.TRUE;
|
||||
} else {
|
||||
this.imagePresent = null;
|
||||
}
|
||||
this.allowedOffices = allowedOffices;
|
||||
this.currentChange = currentChange;
|
||||
this.allChanges = allChanges;
|
||||
this.parentGroups = parentGroups;
|
||||
|
||||
this.clientPendingApprovalAllowed = clientPendingApprovalAllowed;
|
||||
|
||||
// associations
|
||||
this.groups = groups;
|
||||
|
||||
// template
|
||||
this.officeOptions = allowedOffices;
|
||||
}
|
||||
|
||||
public Long id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String displayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
public Long officeId() {
|
||||
return this.officeId;
|
||||
}
|
||||
|
||||
public String officeName() {
|
||||
return this.officeName;
|
||||
}
|
||||
|
||||
public String imageKey() {
|
||||
return this.imageKey;
|
||||
}
|
||||
|
||||
public boolean imageKeyDoesNotExist() {
|
||||
return !imageKeyExists();
|
||||
}
|
||||
|
||||
private boolean imageKeyExists() {
|
||||
return StringUtils.isNotBlank(this.imageKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,38 +172,7 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
.toHashCode();
|
||||
}
|
||||
|
||||
public String displayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
public String officeName() {
|
||||
return this.officeName;
|
||||
}
|
||||
|
||||
private boolean imageKeyExists() {
|
||||
return StringUtils.isNotBlank(this.imageKey);
|
||||
}
|
||||
|
||||
public boolean imageKeyDoesNotExist() {
|
||||
return !imageKeyExists();
|
||||
}
|
||||
|
||||
public String imageKey() {
|
||||
return this.imageKey;
|
||||
}
|
||||
|
||||
public Long id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public Long officeId() {
|
||||
return this.officeId;
|
||||
}
|
||||
|
||||
public ClientData currentChange() {
|
||||
return this.currentChange;
|
||||
}
|
||||
|
||||
// TODO - kw - look into removing usage of the getters below
|
||||
public String getExternalId() {
|
||||
return this.externalId;
|
||||
}
|
||||
@@ -191,15 +185,7 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
return this.lastname;
|
||||
}
|
||||
|
||||
public Long getOfficeId() {
|
||||
return this.officeId;
|
||||
}
|
||||
|
||||
public String getOfficeName() {
|
||||
return this.officeName;
|
||||
}
|
||||
|
||||
public LocalDate getJoinedDate() {
|
||||
return this.joinedDate;
|
||||
public LocalDate getActivationDate() {
|
||||
return this.activationDate;
|
||||
}
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.data;
|
||||
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.activationDateParamName;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
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.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.portfolio.client.api.ClientApiConstants;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Component
|
||||
public final class ClientDataValidator {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public ClientDataValidator(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
public void validateForCreate(final String json, final boolean isPendingApprovalEnabled) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, ClientApiConstants.CLIENT_REQUEST_DATA_PARAMETERS);
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(ClientApiConstants.accountNoParamName, element)) {
|
||||
final String accountNo = fromApiJsonHelper.extractStringNamed(ClientApiConstants.accountNoParamName, element);
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.accountNoParamName).value(accountNo).notBlank().notExceedingLengthOf(20);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(ClientApiConstants.externalIdParamName, element)) {
|
||||
final String externalId = fromApiJsonHelper.extractStringNamed(ClientApiConstants.externalIdParamName, element);
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.externalIdParamName).value(externalId).ignoreIfNull()
|
||||
.notExceedingLengthOf(100);
|
||||
}
|
||||
|
||||
final Long officeId = fromApiJsonHelper.extractLongNamed(ClientApiConstants.officeIdParamName, element);
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.officeIdParamName).value(officeId).notNull().integerGreaterThanZero();
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(ClientApiConstants.groupIdParamName, element)) {
|
||||
final Long groupId = fromApiJsonHelper.extractLongNamed(ClientApiConstants.groupIdParamName, element);
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.groupIdParamName).value(groupId).notNull().integerGreaterThanZero();
|
||||
}
|
||||
|
||||
final Boolean active = fromApiJsonHelper.extractBooleanNamed(ClientApiConstants.activeParamName, element);
|
||||
if (active != null) {
|
||||
if (active.booleanValue()) {
|
||||
final LocalDate joinedDate = fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.activationDateParamName, element);
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.activationDateParamName).value(joinedDate).notNull();
|
||||
} else {
|
||||
if (!isPendingApprovalEnabled) {
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).failWithCode(".pending.status.not.allowed");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).value(active).trueOrFalseRequired(false);
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForUpdate(final String json, final boolean isPendingApprovalEnabled) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, ClientApiConstants.CLIENT_REQUEST_DATA_PARAMETERS);
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
|
||||
boolean atLeastOneParameterPassedForUpdate = false;
|
||||
if (fromApiJsonHelper.parameterExists(ClientApiConstants.accountNoParamName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
final String accountNo = fromApiJsonHelper.extractStringNamed(ClientApiConstants.accountNoParamName, element);
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.accountNoParamName).value(accountNo).notBlank().notExceedingLengthOf(20);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(ClientApiConstants.externalIdParamName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
final String externalId = fromApiJsonHelper.extractStringNamed(ClientApiConstants.externalIdParamName, element);
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.externalIdParamName).value(externalId).notExceedingLengthOf(100);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(ClientApiConstants.fullnameParamName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(ClientApiConstants.lastnameParamName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(ClientApiConstants.middlenameParamName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(ClientApiConstants.firstnameParamName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(ClientApiConstants.officeIdParamName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
final Long officeId = fromApiJsonHelper.extractLongNamed(ClientApiConstants.officeIdParamName, element);
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.officeIdParamName).value(officeId).notNull().integerGreaterThanZero();
|
||||
}
|
||||
|
||||
final Boolean active = fromApiJsonHelper.extractBooleanNamed(ClientApiConstants.activeParamName, element);
|
||||
if (active != null) {
|
||||
if (active.booleanValue()) {
|
||||
final LocalDate joinedDate = fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.activationDateParamName, element);
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.activationDateParamName).value(joinedDate).notNull();
|
||||
} else {
|
||||
if (!isPendingApprovalEnabled) {
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).failWithCode(".pending.status.not.allowed");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).value(active).trueOrFalseRequired(false);
|
||||
}
|
||||
|
||||
if (!atLeastOneParameterPassedForUpdate) {
|
||||
final Object forceError = null;
|
||||
baseDataValidator.reset().anyOfNotNull(forceError);
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateActivation(final JsonCommand command) {
|
||||
final String json = command.json();
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, ClientApiConstants.ACTIVATION_REQUEST_DATA_PARAMETERS);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
|
||||
final JsonElement element = command.parsedJson();
|
||||
|
||||
final LocalDate activationDate = fromApiJsonHelper.extractLocalDateNamed(activationDateParamName, element);
|
||||
baseDataValidator.reset().parameter(activationDateParamName).value(activationDate).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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+109
-26
@@ -27,18 +27,21 @@ import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.infrastructure.security.service.RandomPasswordGenerator;
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
import org.mifosplatform.portfolio.client.api.ClientApiConstants;
|
||||
import org.mifosplatform.portfolio.group.domain.Group;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_client", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_no" }, name = "account_no_UNIQUE") })
|
||||
public class Client extends AbstractPersistable<Long> {
|
||||
public final class Client extends AbstractPersistable<Long> {
|
||||
|
||||
@Column(name = "account_no", length = 20, unique = true, nullable = false)
|
||||
private String accountNumber;
|
||||
@@ -47,6 +50,12 @@ public class Client extends AbstractPersistable<Long> {
|
||||
@JoinColumn(name = "office_id", nullable = false)
|
||||
private Office office;
|
||||
|
||||
/**
|
||||
* A value from {@link ClientStatus}.
|
||||
*/
|
||||
@Column(name = "status_enum", nullable = false)
|
||||
private Integer status;
|
||||
|
||||
@Column(name = "firstname", length = 50)
|
||||
private String firstname;
|
||||
|
||||
@@ -60,61 +69,80 @@ public class Client extends AbstractPersistable<Long> {
|
||||
private String fullname;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "display_name", length = 100)
|
||||
@Column(name = "display_name", length = 100, nullable = false)
|
||||
private String displayName;
|
||||
|
||||
@Column(name = "joined_date")
|
||||
@Column(name = "activation_date", nullable = true)
|
||||
@Temporal(TemporalType.DATE)
|
||||
private Date joinedDate;
|
||||
private Date activationDate;
|
||||
|
||||
@Column(name = "external_id", length = 100, unique = true)
|
||||
@Column(name = "external_id", length = 100, nullable = true, unique = true)
|
||||
private String externalId;
|
||||
|
||||
@Column(name = "is_deleted", nullable = false)
|
||||
private boolean deleted = false;
|
||||
|
||||
@Column(name = "image_key", length = 500)
|
||||
@Column(name = "image_key", length = 500, nullable = true)
|
||||
private String imageKey;
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(name = "m_group_client", joinColumns = @JoinColumn(name = "client_id"), inverseJoinColumns = @JoinColumn(name = "group_id"))
|
||||
private Set<Group> parentGroups;
|
||||
private Set<Group> groups;
|
||||
|
||||
@Transient
|
||||
private boolean accountNumberRequiresAutoGeneration = false;
|
||||
|
||||
public static Client fromJson(final Office clientOffice, final Group clientParentGroup, final JsonCommand command) {
|
||||
public static Client createNew(final Office clientOffice, final Group clientParentGroup, final JsonCommand command,
|
||||
final boolean isPendingStateAllowed) {
|
||||
|
||||
final String accountNo = command.stringValueOfParameterNamed("accountNo");
|
||||
final String firstname = command.stringValueOfParameterNamed("firstname");
|
||||
final String middlename = command.stringValueOfParameterNamed("middlename");
|
||||
final String lastname = command.stringValueOfParameterNamed("lastname");
|
||||
final String fullname = command.stringValueOfParameterNamed("fullname");
|
||||
final LocalDate joiningDate = command.localDateValueOfParameterNamed("joinedDate");
|
||||
final String externalId = command.stringValueOfParameterNamed("externalId");
|
||||
final String accountNo = command.stringValueOfParameterNamed(ClientApiConstants.accountNoParamName);
|
||||
final String externalId = command.stringValueOfParameterNamed(ClientApiConstants.externalIdParamName);
|
||||
|
||||
return new Client(clientOffice, clientParentGroup, accountNo, firstname, middlename, lastname, fullname, joiningDate, externalId);
|
||||
final String firstname = command.stringValueOfParameterNamed(ClientApiConstants.firstnameParamName);
|
||||
final String middlename = command.stringValueOfParameterNamed(ClientApiConstants.middlenameParamName);
|
||||
final String lastname = command.stringValueOfParameterNamed(ClientApiConstants.lastnameParamName);
|
||||
final String fullname = command.stringValueOfParameterNamed(ClientApiConstants.fullnameParamName);
|
||||
|
||||
ClientStatus status = ClientStatus.ACTIVE;
|
||||
boolean active = true;
|
||||
if (isPendingStateAllowed && command.hasParameter("active")) {
|
||||
active = command.booleanPrimitiveValueOfParameterNamed(ClientApiConstants.activeParamName);
|
||||
}
|
||||
|
||||
LocalDate activationDate = null;
|
||||
if (active) {
|
||||
activationDate = command.localDateValueOfParameterNamed(ClientApiConstants.activationDateParamName);
|
||||
} else {
|
||||
status = ClientStatus.PENDING;
|
||||
}
|
||||
|
||||
return new Client(status, clientOffice, clientParentGroup, accountNo, firstname, middlename, lastname, fullname, activationDate,
|
||||
externalId);
|
||||
}
|
||||
|
||||
protected Client() {
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
private Client(final Office office, final Group clientParentGroup, final String accountNo, final String firstname,
|
||||
final String middlename, final String lastname, final String fullname, final LocalDate openingDate, final String externalId) {
|
||||
private Client(final ClientStatus status, final Office office, final Group clientParentGroup, final String accountNo,
|
||||
final String firstname, final String middlename, final String lastname, final String fullname, final LocalDate activationDate,
|
||||
final String externalId) {
|
||||
if (StringUtils.isBlank(accountNo)) {
|
||||
this.accountNumber = new RandomPasswordGenerator(19).generate();
|
||||
this.accountNumberRequiresAutoGeneration = true;
|
||||
} else {
|
||||
this.accountNumber = accountNo;
|
||||
}
|
||||
this.status = status.getValue();
|
||||
this.office = office;
|
||||
if (StringUtils.isNotBlank(externalId)) {
|
||||
this.externalId = externalId.trim();
|
||||
} else {
|
||||
this.externalId = null;
|
||||
}
|
||||
this.joinedDate = openingDate.toDateMidnight().toDate();
|
||||
if (activationDate != null) {
|
||||
this.activationDate = activationDate.toDateMidnight().toDate();
|
||||
}
|
||||
if (StringUtils.isNotBlank(firstname)) {
|
||||
this.firstname = firstname.trim();
|
||||
} else {
|
||||
@@ -140,8 +168,8 @@ public class Client extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
if (clientParentGroup != null) {
|
||||
this.parentGroups = new HashSet<Group>();
|
||||
this.parentGroups.add(clientParentGroup);
|
||||
this.groups = new HashSet<Group>();
|
||||
this.groups.add(clientParentGroup);
|
||||
}
|
||||
|
||||
deriveDisplayName();
|
||||
@@ -173,10 +201,65 @@ public class Client extends AbstractPersistable<Long> {
|
||||
this.accountNumberRequiresAutoGeneration = false;
|
||||
}
|
||||
|
||||
public void activate(final DateTimeFormatter formatter, final LocalDate activationLocalDate) {
|
||||
if (isActive()) {
|
||||
final String defaultUserMessage = "Cannot activate client. Client is already active.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.clients.already.active", defaultUserMessage,
|
||||
"activationDate", activationLocalDate.toString(formatter));
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
dataValidationErrors.add(error);
|
||||
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
|
||||
if (isDateInTheFuture(activationLocalDate)) {
|
||||
|
||||
final String defaultUserMessage = "Activation date cannot be in the future.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.clients.activationDate.in.the.future",
|
||||
defaultUserMessage, "activationDate", activationLocalDate);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
dataValidationErrors.add(error);
|
||||
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
|
||||
this.activationDate = activationLocalDate.toDate();
|
||||
this.status = ClientStatus.ACTIVE.getValue();
|
||||
}
|
||||
|
||||
public boolean isNotActive() {
|
||||
return !isActive();
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return ClientStatus.fromInt(this.status).isActive();
|
||||
}
|
||||
|
||||
public boolean isNotPending() {
|
||||
return !isPending();
|
||||
}
|
||||
|
||||
public boolean isPending() {
|
||||
return ClientStatus.fromInt(this.status).isPending();
|
||||
}
|
||||
|
||||
private boolean isDateInTheFuture(final LocalDate localDate) {
|
||||
return localDate.isAfter(DateUtils.getLocalDateOfTenant());
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command) {
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(9);
|
||||
|
||||
final String statusEnumParamName = "status";
|
||||
if (command.isChangeInIntegerParameterNamed(statusEnumParamName, this.status)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(statusEnumParamName);
|
||||
actualChanges.put(statusEnumParamName, ClientEnumerations.status(newValue));
|
||||
this.status = ClientStatus.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
final String accountNoParamName = "accountNo";
|
||||
if (command.isChangeInStringParameterNamed(accountNoParamName, this.accountNumber)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(accountNoParamName);
|
||||
@@ -238,7 +321,7 @@ public class Client extends AbstractPersistable<Long> {
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
|
||||
final LocalDate newValue = command.localDateValueOfParameterNamed(joiningDateParamName);
|
||||
this.joinedDate = newValue.toDate();
|
||||
this.activationDate = newValue.toDate();
|
||||
}
|
||||
|
||||
deriveDisplayName();
|
||||
@@ -297,8 +380,8 @@ public class Client extends AbstractPersistable<Long> {
|
||||
|
||||
private LocalDate getJoiningLocalDate() {
|
||||
LocalDate joiningLocalDate = null;
|
||||
if (this.joinedDate != null) {
|
||||
joiningLocalDate = LocalDate.fromDateFields(this.joinedDate);
|
||||
if (this.activationDate != null) {
|
||||
joiningLocalDate = LocalDate.fromDateFields(this.activationDate);
|
||||
}
|
||||
return joiningLocalDate;
|
||||
}
|
||||
@@ -335,7 +418,7 @@ public class Client extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public Date getJoiningDate() {
|
||||
return joinedDate;
|
||||
return activationDate;
|
||||
}
|
||||
|
||||
public String getExternalId() {
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.domain;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
|
||||
public class ClientEnumerations {
|
||||
|
||||
public static EnumOptionData status(final Integer statusId) {
|
||||
return status(ClientStatus.fromInt(statusId));
|
||||
}
|
||||
|
||||
public static EnumOptionData status(final ClientStatus status) {
|
||||
EnumOptionData optionData = new EnumOptionData(ClientStatus.INVALID.getValue().longValue(), ClientStatus.INVALID.getCode(),
|
||||
"Invalid");
|
||||
switch (status) {
|
||||
case INVALID:
|
||||
optionData = new EnumOptionData(ClientStatus.INVALID.getValue().longValue(), ClientStatus.INVALID.getCode(), "Invalid");
|
||||
break;
|
||||
case PENDING:
|
||||
optionData = new EnumOptionData(ClientStatus.PENDING.getValue().longValue(), ClientStatus.PENDING.getCode(), "Pending");
|
||||
break;
|
||||
case ACTIVE:
|
||||
optionData = new EnumOptionData(ClientStatus.ACTIVE.getValue().longValue(), ClientStatus.ACTIVE.getCode(), "Active");
|
||||
break;
|
||||
case CLOSED:
|
||||
optionData = new EnumOptionData(ClientStatus.CLOSED.getValue().longValue(), ClientStatus.CLOSED.getCode(), "Closed");
|
||||
break;
|
||||
}
|
||||
|
||||
return optionData;
|
||||
}
|
||||
}
|
||||
+12
-1
@@ -27,8 +27,19 @@ public class ClientRepositoryWrapper {
|
||||
|
||||
public Client findOneWithNotFoundDetection(final Long id) {
|
||||
final Client client = this.repository.findOne(id);
|
||||
if (client == null) { throw new ClientNotFoundException(id); }
|
||||
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(id); }
|
||||
return client;
|
||||
}
|
||||
|
||||
public void save(final Client client) {
|
||||
this.repository.save(client);
|
||||
}
|
||||
|
||||
public void saveAndFlush(final Client client) {
|
||||
this.repository.saveAndFlush(client);
|
||||
}
|
||||
|
||||
public void delete(final Client client) {
|
||||
this.repository.delete(client);
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.domain;
|
||||
|
||||
/**
|
||||
* Enum representation of client status states.
|
||||
*/
|
||||
public enum ClientStatus {
|
||||
|
||||
INVALID(0, "clientStatusType.invalid"), //
|
||||
PENDING(100, "clientStatusType.pending"), //
|
||||
ACTIVE(300, "clientStatusType.active"), //
|
||||
CLOSED(600, "clientStatusType.closed");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
public static ClientStatus fromInt(final Integer statusValue) {
|
||||
|
||||
ClientStatus enumeration = ClientStatus.INVALID;
|
||||
switch (statusValue) {
|
||||
case 100:
|
||||
enumeration = ClientStatus.PENDING;
|
||||
break;
|
||||
case 300:
|
||||
enumeration = ClientStatus.ACTIVE;
|
||||
break;
|
||||
case 600:
|
||||
enumeration = ClientStatus.CLOSED;
|
||||
break;
|
||||
}
|
||||
return enumeration;
|
||||
}
|
||||
|
||||
private ClientStatus(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public boolean hasStateOf(final ClientStatus state) {
|
||||
return this.value.equals(state.getValue());
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public boolean isPending() {
|
||||
return this.value.equals(ClientStatus.PENDING.getValue());
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this.value.equals(ClientStatus.ACTIVE.getValue());
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return this.value.equals(ClientStatus.CLOSED.getValue());
|
||||
}
|
||||
}
|
||||
+4
-7
@@ -11,12 +11,9 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
|
||||
* A {@link RuntimeException} thrown when client Identifier resources are not
|
||||
* found.
|
||||
*/
|
||||
public class ClientIdentifierNotFoundException extends
|
||||
AbstractPlatformResourceNotFoundException {
|
||||
public class ClientIdentifierNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public ClientIdentifierNotFoundException(Long id) {
|
||||
super("error.msg.clientIdentifier.id.invalid",
|
||||
"Client Identifier with the primary key " + id
|
||||
+ " does not exist", id);
|
||||
}
|
||||
public ClientIdentifierNotFoundException(final Long id) {
|
||||
super("error.msg.clientIdentifier.id.invalid", "Client Identifier with the primary key " + id + " does not exist", id);
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when attempting to delete clients
|
||||
*/
|
||||
public class ClientMustBePendingToBeDeletedException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public ClientMustBePendingToBeDeletedException(final Long id) {
|
||||
super("error.msg.clients.cannot.be.deleted",
|
||||
"Client with identifier " + id + " cannot be deleted as it is not in `Pending` state.", id);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -12,7 +12,7 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
|
||||
*/
|
||||
public class ClientNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public ClientNotFoundException(Long id) {
|
||||
super("error.msg.client.id.invalid", "Client with identifier " + id + " does not exist", id);
|
||||
}
|
||||
public ClientNotFoundException(final Long id) {
|
||||
super("error.msg.client.id.invalid", "Client with identifier " + id + " does not exist", id);
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.client.service.ClientWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class ActivateClientCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final ClientWritePlatformService clientWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public ActivateClientCommandHandler(final ClientWritePlatformService clientWritePlatformService) {
|
||||
this.clientWritePlatformService = clientWritePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
return this.clientWritePlatformService.activateClient(command.entityId(), command);
|
||||
}
|
||||
}
|
||||
-196
@@ -1,196 +0,0 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.client.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.joda.time.LocalDate;
|
||||
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.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.portfolio.client.command.ClientCommand;
|
||||
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 ClientCommand}
|
||||
* 's.
|
||||
*/
|
||||
@Component
|
||||
public final class ClientCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<ClientCommand> {
|
||||
|
||||
/**
|
||||
* The parameters supported for this command.
|
||||
*/
|
||||
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("id", "accountNo", "externalId", "firstname",
|
||||
"middlename", "lastname", "fullname", "officeId", "joinedDate", "locale", "dateFormat", "groupId"));
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public ClientCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientCommand commandFromApiJson(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 JsonElement element = fromApiJsonHelper.parse(json);
|
||||
final String accountNo = fromApiJsonHelper.extractStringNamed("accountNo", element);
|
||||
final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element);
|
||||
final String firstname = fromApiJsonHelper.extractStringNamed("firstname", element);
|
||||
final String middlename = fromApiJsonHelper.extractStringNamed("middlename", element);
|
||||
final String lastname = fromApiJsonHelper.extractStringNamed("lastname", element);
|
||||
final String fullname = fromApiJsonHelper.extractStringNamed("fullname", element);
|
||||
final Long officeId = fromApiJsonHelper.extractLongNamed("officeId", element);
|
||||
final LocalDate joiningDate = fromApiJsonHelper.extractLocalDateNamed("joinedDate", element);
|
||||
|
||||
return new ClientCommand(accountNo, externalId, firstname, middlename, lastname, fullname, officeId, joiningDate);
|
||||
}
|
||||
|
||||
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 JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("client");
|
||||
|
||||
boolean atLeastOneParameterPassedForUpdate = false;
|
||||
final String accountNoParameterName = "accountNo";
|
||||
if (fromApiJsonHelper.parameterExists(accountNoParameterName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
final String accountNo = fromApiJsonHelper.extractStringNamed(accountNoParameterName, element);
|
||||
baseDataValidator.reset().parameter(accountNoParameterName).value(accountNo).notBlank().notExceedingLengthOf(20);
|
||||
}
|
||||
|
||||
final String externalIdParameterName = "externalId";
|
||||
if (fromApiJsonHelper.parameterExists(externalIdParameterName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
final String externalId = fromApiJsonHelper.extractStringNamed(externalIdParameterName, element);
|
||||
baseDataValidator.reset().parameter(externalIdParameterName).value(externalId).ignoreIfNull().notExceedingLengthOf(100);
|
||||
}
|
||||
|
||||
final String fullnameParameterName = "fullname";
|
||||
if (fromApiJsonHelper.parameterExists(fullnameParameterName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
}
|
||||
|
||||
final String lastNameParameterName = "lastname";
|
||||
if (fromApiJsonHelper.parameterExists(lastNameParameterName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
}
|
||||
|
||||
final String middleNameParameterName = "middlename";
|
||||
if (fromApiJsonHelper.parameterExists(middleNameParameterName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
}
|
||||
|
||||
final String firstNameParameterName = "firstname";
|
||||
if (fromApiJsonHelper.parameterExists(firstNameParameterName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
}
|
||||
|
||||
final String officeIdParameterName = "officeId";
|
||||
if (fromApiJsonHelper.parameterExists(officeIdParameterName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
final Long officeId = fromApiJsonHelper.extractLongNamed(officeIdParameterName, element);
|
||||
baseDataValidator.reset().parameter(officeIdParameterName).value(officeId).notNull().integerGreaterThanZero();
|
||||
}
|
||||
|
||||
final String joinedDateParameterName = "joinedDate";
|
||||
if (fromApiJsonHelper.parameterExists(joinedDateParameterName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
|
||||
final String joinedDateStr = fromApiJsonHelper.extractStringNamed(joinedDateParameterName, element);
|
||||
baseDataValidator.reset().parameter(joinedDateParameterName).value(joinedDateStr).notBlank();
|
||||
|
||||
final LocalDate joinedDate = fromApiJsonHelper.extractLocalDateNamed(joinedDateParameterName, element);
|
||||
baseDataValidator.reset().parameter(joinedDateParameterName).value(joinedDate).notNull();
|
||||
}
|
||||
|
||||
if (!atLeastOneParameterPassedForUpdate) {
|
||||
final Object forceError = null;
|
||||
baseDataValidator.reset().anyOfNotNull(forceError);
|
||||
}
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
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 JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("client");
|
||||
|
||||
final String accountNoParameterName = "accountNo";
|
||||
if (fromApiJsonHelper.parameterExists(accountNoParameterName, element)) {
|
||||
final String accountNo = fromApiJsonHelper.extractStringNamed(accountNoParameterName, element);
|
||||
baseDataValidator.reset().parameter(accountNoParameterName).value(accountNo).notBlank().notExceedingLengthOf(20);
|
||||
}
|
||||
|
||||
final String externalIdParameterName = "externalId";
|
||||
if (fromApiJsonHelper.parameterExists(externalIdParameterName, element)) {
|
||||
final String externalId = fromApiJsonHelper.extractStringNamed(externalIdParameterName, element);
|
||||
baseDataValidator.reset().parameter(externalIdParameterName).value(externalId).ignoreIfNull().notExceedingLengthOf(100);
|
||||
}
|
||||
|
||||
final String officeIdParameterName = "officeId";
|
||||
if (fromApiJsonHelper.parameterExists(officeIdParameterName, element)) {
|
||||
final Long officeId = fromApiJsonHelper.extractLongNamed(officeIdParameterName, element);
|
||||
baseDataValidator.reset().parameter(officeIdParameterName).value(officeId).notNull().integerGreaterThanZero();
|
||||
}
|
||||
|
||||
final String groupIdParameterName = "groupId";
|
||||
if (fromApiJsonHelper.parameterExists(groupIdParameterName, element)) {
|
||||
final Long groupId = fromApiJsonHelper.extractLongNamed(groupIdParameterName, element);
|
||||
baseDataValidator.reset().parameter(groupIdParameterName).value(groupId).notNull().integerGreaterThanZero();
|
||||
}
|
||||
|
||||
final String joinedDateParameterName = "joinedDate";
|
||||
if (fromApiJsonHelper.parameterExists(joinedDateParameterName, element)) {
|
||||
|
||||
final String joinedDateStr = fromApiJsonHelper.extractStringNamed(joinedDateParameterName, element);
|
||||
baseDataValidator.reset().parameter(joinedDateParameterName).value(joinedDateStr).notBlank();
|
||||
|
||||
final LocalDate joinedDate = fromApiJsonHelper.extractLocalDateNamed(joinedDateParameterName, element);
|
||||
baseDataValidator.reset().parameter(joinedDateParameterName).value(joinedDate).notNull();
|
||||
}
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
+6
-5
@@ -10,18 +10,19 @@ import java.util.Collection;
|
||||
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData;
|
||||
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData;
|
||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||
import org.mifosplatform.portfolio.group.service.SearchParameters;
|
||||
|
||||
public interface ClientReadPlatformService {
|
||||
|
||||
Collection<ClientData> retrieveAllIndividualClients(String extraCriteria);
|
||||
ClientData retrieveTemplate();
|
||||
|
||||
ClientData retrieveIndividualClient(Long clientId);
|
||||
Collection<ClientData> retrieveAll(SearchParameters searchParameters);
|
||||
|
||||
ClientData retrieveNewClientDetails();
|
||||
ClientData retrieveOne(Long clientId);
|
||||
|
||||
Collection<ClientData> retrieveAllIndividualClientsForLookup(String extraCriteria);
|
||||
Collection<ClientData> retrieveAllForLookup(String extraCriteria);
|
||||
|
||||
Collection<ClientData> retrieveAllIndividualClientsForLookupByOfficeId(Long officeId);
|
||||
Collection<ClientData> retrieveAllForLookupByOfficeId(Long officeId);
|
||||
|
||||
ClientAccountSummaryCollectionData retrieveClientAccountDetails(Long clientId);
|
||||
|
||||
|
||||
+140
-54
@@ -13,16 +13,21 @@ import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.office.data.OfficeLookup;
|
||||
import org.mifosplatform.organisation.office.data.OfficeData;
|
||||
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
|
||||
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData;
|
||||
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData;
|
||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientEnumerations;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
||||
import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
||||
import org.mifosplatform.portfolio.group.service.SearchParameters;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanStatusEnumData;
|
||||
import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
@@ -37,61 +42,126 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final PlatformSecurityContext context;
|
||||
private final ConfigurationDomainService configurationDomainService;
|
||||
private final OfficeReadPlatformService officeReadPlatformService;
|
||||
|
||||
// data mappers
|
||||
private final ClientMapper clientMapper = new ClientMapper();
|
||||
private final ClientLookupMapper lookupMapper = new ClientLookupMapper();
|
||||
private final ClientMembersOfGroupMapper membersOfGroupMapper = new ClientMembersOfGroupMapper();
|
||||
private final ParentGroupsMapper clientGroupsMapper = new ParentGroupsMapper();
|
||||
|
||||
@Autowired
|
||||
public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
|
||||
final OfficeReadPlatformService officeReadPlatformService) {
|
||||
final ConfigurationDomainService configurationDomainService, final OfficeReadPlatformService officeReadPlatformService) {
|
||||
this.context = context;
|
||||
this.configurationDomainService = configurationDomainService;
|
||||
this.officeReadPlatformService = officeReadPlatformService;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ClientData> retrieveAllIndividualClients(final String extraCriteria) {
|
||||
public ClientData retrieveTemplate() {
|
||||
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
String hierarchy = currentUser.getOffice().getHierarchy();
|
||||
String hierarchySearchString = hierarchy + "%";
|
||||
final AppUser currentUser = context.authenticatedUser();
|
||||
|
||||
ClientMapper rm = new ClientMapper();
|
||||
final Collection<OfficeData> offices = officeReadPlatformService.retrieveAllOfficesForDropdown();
|
||||
|
||||
String sql = "select " + rm.clientSchema();
|
||||
final boolean clientPendingApprovalAllowed = this.configurationDomainService.isClientPendingApprovalAllowedEnabled();
|
||||
|
||||
final Long officeId = currentUser.getOffice().getId();
|
||||
|
||||
return ClientData.template(officeId, new LocalDate(), clientPendingApprovalAllowed, offices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ClientData> retrieveAll(final SearchParameters searchParameters) {
|
||||
|
||||
final AppUser currentUser = context.authenticatedUser();
|
||||
final String hierarchy = currentUser.getOffice().getHierarchy();
|
||||
final String hierarchySearchString = hierarchy + "%";
|
||||
|
||||
String sql = "select " + this.clientMapper.schema() + " where o.hierarchy like ? and c.is_deleted=0";
|
||||
|
||||
final String extraCriteria = buildSqlStringFromClientCriteria(searchParameters);
|
||||
|
||||
if (StringUtils.isNotBlank(extraCriteria)) sql += " and (" + extraCriteria + ")";
|
||||
|
||||
sql += " order by c.display_name ASC, c.account_no ASC";
|
||||
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { hierarchySearchString });
|
||||
return this.jdbcTemplate.query(sql, clientMapper, new Object[] { hierarchySearchString });
|
||||
}
|
||||
|
||||
private String buildSqlStringFromClientCriteria(final SearchParameters searchParameters) {
|
||||
|
||||
final String sqlSearch = searchParameters.getSqlSearch();
|
||||
final Long officeId = searchParameters.getOfficeId();
|
||||
final String externalId = searchParameters.getExternalId();
|
||||
final String displayName = searchParameters.getName();
|
||||
final String firstname = searchParameters.getFirstname();
|
||||
final String lastname = searchParameters.getLastname();
|
||||
final String hierarchy = searchParameters.getHierarchy();
|
||||
|
||||
String extraCriteria = "";
|
||||
if (sqlSearch != null) {
|
||||
extraCriteria = " and (" + sqlSearch + ")";
|
||||
}
|
||||
|
||||
if (officeId != null) {
|
||||
extraCriteria += " and office_id = " + officeId;
|
||||
}
|
||||
|
||||
if (externalId != null) {
|
||||
extraCriteria += " and external_id like " + ApiParameterHelper.sqlEncodeString(externalId);
|
||||
}
|
||||
|
||||
if (displayName != null) {
|
||||
extraCriteria += " and concat(ifnull(firstname, ''), if(firstname > '',' ', '') , ifnull(lastname, '')) like "
|
||||
+ ApiParameterHelper.sqlEncodeString(displayName);
|
||||
}
|
||||
|
||||
if (firstname != null) {
|
||||
extraCriteria += " and firstname like " + ApiParameterHelper.sqlEncodeString(firstname);
|
||||
}
|
||||
|
||||
if (lastname != null) {
|
||||
extraCriteria += " and lastname like " + ApiParameterHelper.sqlEncodeString(lastname);
|
||||
}
|
||||
|
||||
if (hierarchy != null) {
|
||||
extraCriteria += " and o.hierarchy like " + ApiParameterHelper.sqlEncodeString(hierarchy + "%");
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
extraCriteria = extraCriteria.substring(4);
|
||||
}
|
||||
|
||||
return extraCriteria;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientData retrieveIndividualClient(final Long clientId) {
|
||||
public ClientData retrieveOne(final Long clientId) {
|
||||
|
||||
try {
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
String hierarchy = currentUser.getOffice().getHierarchy();
|
||||
String hierarchySearchString = hierarchy + "%";
|
||||
|
||||
ClientMapper rm = new ClientMapper();
|
||||
String sql = "select " + rm.clientSchema() + " and c.id = " + clientId;
|
||||
ClientData clientData = this.jdbcTemplate.queryForObject(sql, rm, new Object[] { hierarchySearchString });
|
||||
String sql = "select " + this.clientMapper.schema() + " where o.hierarchy like ? and c.is_deleted=0 and c.id = ?";
|
||||
ClientData clientData = this.jdbcTemplate.queryForObject(sql, this.clientMapper,
|
||||
new Object[] { hierarchySearchString, clientId });
|
||||
|
||||
ParentGroupsMapper cgrm = new ParentGroupsMapper();
|
||||
String cgSql = "select " + cgrm.parentGroupsSchema();
|
||||
Collection<GroupGeneralData> parentGroups = this.jdbcTemplate.query(cgSql, cgrm, new Object[] { clientId });
|
||||
|
||||
return ClientData.setParentGroups(clientData , parentGroups);
|
||||
|
||||
String clientGroupsSql = "select " + this.clientGroupsMapper.parentGroupsSchema();
|
||||
|
||||
Collection<GroupGeneralData> parentGroups = this.jdbcTemplate.query(clientGroupsSql, this.clientGroupsMapper, new Object[] { clientId });
|
||||
return ClientData.setParentGroups(clientData, parentGroups);
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
throw new ClientNotFoundException(clientId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ClientData> retrieveAllIndividualClientsForLookup(final String extraCriteria) {
|
||||
public Collection<ClientData> retrieveAllForLookup(final String extraCriteria) {
|
||||
|
||||
String sql = "select " + this.lookupMapper.schema();
|
||||
|
||||
@@ -103,24 +173,13 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ClientData> retrieveAllIndividualClientsForLookupByOfficeId(final Long officeId) {
|
||||
public Collection<ClientData> retrieveAllForLookupByOfficeId(final Long officeId) {
|
||||
|
||||
final String sql = "select " + this.lookupMapper.schema() + " and c.office_id = ?";
|
||||
|
||||
return this.jdbcTemplate.query(sql, this.lookupMapper, new Object[] { officeId });
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientData retrieveNewClientDetails() {
|
||||
|
||||
final AppUser currentUser = context.authenticatedUser();
|
||||
|
||||
final List<OfficeLookup> offices = new ArrayList<OfficeLookup>(officeReadPlatformService.retrieveAllOfficesForLookup());
|
||||
final Long officeId = currentUser.getOffice().getId();
|
||||
|
||||
return ClientData.template(officeId, new LocalDate(), offices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ClientData> retrieveClientMembersOfGroup(final Long groupId) {
|
||||
|
||||
@@ -140,16 +199,16 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
|
||||
public ClientMembersOfGroupMapper() {
|
||||
final StringBuilder sqlBuilder = new StringBuilder(200);
|
||||
|
||||
|
||||
sqlBuilder.append("c.id as id, c.account_no as accountNo, c.external_id as externalId, ");
|
||||
sqlBuilder.append("c.office_id as officeId, o.name as officeName, ");
|
||||
sqlBuilder.append("c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, ");
|
||||
sqlBuilder.append("c.fullname as fullname, c.display_name as displayName, ");
|
||||
sqlBuilder.append("c.joined_date as joinedDate, c.image_key as imagekey ");
|
||||
sqlBuilder.append("c.activation_date as activationDate, c.image_key as imagekey ");
|
||||
sqlBuilder.append("from m_client c ");
|
||||
sqlBuilder.append("join m_office o on o.id = c.office_id ");
|
||||
sqlBuilder.append("join m_group_client pgc on pgc.client_id = c.id");
|
||||
|
||||
|
||||
this.schema = sqlBuilder.toString();
|
||||
}
|
||||
|
||||
@@ -161,6 +220,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
public ClientData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final String accountNo = rs.getString("accountNo");
|
||||
|
||||
final EnumOptionData status = null;
|
||||
|
||||
final Long officeId = JdbcSupport.getLong(rs, "officeId");
|
||||
final Long id = JdbcSupport.getLong(rs, "id");
|
||||
final String firstname = rs.getString("firstname");
|
||||
@@ -169,29 +231,46 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
final String fullname = rs.getString("fullname");
|
||||
final String displayName = rs.getString("displayName");
|
||||
final String externalId = rs.getString("externalId");
|
||||
final LocalDate joinedDate = JdbcSupport.getLocalDate(rs, "joinedDate");
|
||||
final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate");
|
||||
final String imageKey = rs.getString("imageKey");
|
||||
final String officeName = rs.getString("officeName");
|
||||
|
||||
return new ClientData(accountNo, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, externalId,
|
||||
joinedDate, imageKey, null, null, null, null);
|
||||
return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName,
|
||||
externalId, activationDate, imageKey, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ClientMapper implements RowMapper<ClientData> {
|
||||
|
||||
public String clientSchema() {
|
||||
return "c.account_no as accountNo, c.office_id as officeId, o.name as officeName, c.id as id, "
|
||||
+ "c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, "
|
||||
+ "c.fullname as fullname, c.display_name as displayName, "
|
||||
+ "c.external_id as externalId, c.joined_date as joinedDate, c.image_key as imagekey from m_client c join m_office o on o.id = c.office_id "
|
||||
+ " where o.hierarchy like ? and c.is_deleted=0 ";
|
||||
private final String schema;
|
||||
|
||||
public ClientMapper() {
|
||||
StringBuilder builder = new StringBuilder(400);
|
||||
|
||||
builder.append("c.id as id, c.account_no as accountNo, c.external_id as externalId, c.status_enum as statusEnum, ");
|
||||
builder.append("c.office_id as officeId, o.name as officeName, ");
|
||||
builder.append("c.office_id as officeId, o.name as officeName, ");
|
||||
builder.append("c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, ");
|
||||
builder.append("c.fullname as fullname, c.display_name as displayName, ");
|
||||
builder.append("c.activation_date as activationDate, c.image_key as imagekey ");
|
||||
builder.append("from m_client c ");
|
||||
builder.append("join m_office o on o.id = c.office_id ");
|
||||
|
||||
this.schema = builder.toString();
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
return this.schema;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final String accountNo = rs.getString("accountNo");
|
||||
|
||||
final Integer statusEnum = JdbcSupport.getInteger(rs, "statusEnum");
|
||||
final EnumOptionData status = ClientEnumerations.status(statusEnum);
|
||||
|
||||
final Long officeId = JdbcSupport.getLong(rs, "officeId");
|
||||
final Long id = JdbcSupport.getLong(rs, "id");
|
||||
final String firstname = rs.getString("firstname");
|
||||
@@ -200,12 +279,12 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
final String fullname = rs.getString("fullname");
|
||||
final String displayName = rs.getString("displayName");
|
||||
final String externalId = rs.getString("externalId");
|
||||
final LocalDate joinedDate = JdbcSupport.getLocalDate(rs, "joinedDate");
|
||||
final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate");
|
||||
final String imageKey = rs.getString("imageKey");
|
||||
final String officeName = rs.getString("officeName");
|
||||
|
||||
return new ClientData(accountNo, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, externalId,
|
||||
joinedDate, imageKey, null, null, null ,null);
|
||||
return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName,
|
||||
externalId, activationDate, imageKey, null, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -215,7 +294,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
public String parentGroupsSchema() {
|
||||
return "gp.id As groupId , gp.name As groupName from m_client cl JOIN m_group_client gc ON cl.id = gc.client_id "
|
||||
+ "JOIN m_group gp ON gp.id = gc.group_id WHERE cl.id = ? AND gp.is_deleted = 0 ";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupGeneralData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
@@ -266,7 +345,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
this.context.authenticatedUser();
|
||||
|
||||
// Check if client exists
|
||||
retrieveIndividualClient(clientId);
|
||||
retrieveOne(clientId);
|
||||
|
||||
List<ClientAccountSummaryData> pendingApprovalLoans = new ArrayList<ClientAccountSummaryData>();
|
||||
List<ClientAccountSummaryData> awaitingDisbursalLoans = new ArrayList<ClientAccountSummaryData>();
|
||||
@@ -332,7 +411,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
this.context.authenticatedUser();
|
||||
|
||||
// Check if client exists
|
||||
retrieveIndividualClient(clientId);
|
||||
retrieveOne(clientId);
|
||||
|
||||
ClientLoanAccountSummaryDataMapper rm = new ClientLoanAccountSummaryDataMapper();
|
||||
|
||||
@@ -417,9 +496,11 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
private static final class ClientIdentifierMapper implements RowMapper<ClientData> {
|
||||
|
||||
public String clientLookupByIdentifierSchema() {
|
||||
return "c.id as id, c.account_no as accountNo, c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, "
|
||||
+ "c.fullname as fullname, c.display_name as displayName," + "c.office_id as officeId, o.name as officeName "
|
||||
+ " from m_client c, m_office o, m_client_identifier ci " + "where o.id = c.office_id and c.id=ci.client_id "
|
||||
return "c.id as id, c.account_no as accountNo, c.status_enum as statusEnum, c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, "
|
||||
+ "c.fullname as fullname, c.display_name as displayName,"
|
||||
+ "c.office_id as officeId, o.name as officeName "
|
||||
+ " from m_client c, m_office o, m_client_identifier ci "
|
||||
+ "where o.id = c.office_id and c.id=ci.client_id "
|
||||
+ "and ci.document_type_id= ? and ci.document_key like ?";
|
||||
}
|
||||
|
||||
@@ -428,6 +509,10 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
|
||||
final Long id = rs.getLong("id");
|
||||
final String accountNo = rs.getString("accountNo");
|
||||
|
||||
final Integer statusEnum = JdbcSupport.getInteger(rs, "statusEnum");
|
||||
final EnumOptionData status = ClientEnumerations.status(statusEnum);
|
||||
|
||||
final String firstname = rs.getString("firstname");
|
||||
final String middlename = rs.getString("middlename");
|
||||
final String lastname = rs.getString("lastname");
|
||||
@@ -437,7 +522,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
final Long officeId = rs.getLong("officeId");
|
||||
final String officeName = rs.getString("officeName");
|
||||
|
||||
return ClientData.clientIdentifier(id, accountNo, firstname, middlename, lastname, fullname, displayName, officeId, officeName);
|
||||
return ClientData.clientIdentifier(id, accountNo, status, firstname, middlename, lastname, fullname, displayName, officeId,
|
||||
officeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -18,6 +18,8 @@ public interface ClientWritePlatformService {
|
||||
|
||||
CommandProcessingResult updateClient(Long clientId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult activateClient(Long clientId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult deleteClient(Long clientId);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE')")
|
||||
@@ -28,5 +30,4 @@ public interface ClientWritePlatformService {
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_CLIENTIMAGE')")
|
||||
CommandProcessingResult deleteClientImage(Long clientId);
|
||||
|
||||
}
|
||||
+79
-27
@@ -8,9 +8,15 @@ package org.mifosplatform.portfolio.client.service;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
@@ -22,15 +28,19 @@ 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.portfolio.client.api.ClientApiConstants;
|
||||
import org.mifosplatform.portfolio.client.data.ClientDataValidator;
|
||||
import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator;
|
||||
import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientRepository;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientMustBePendingToBeDeletedException;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
||||
import org.mifosplatform.portfolio.client.serialization.ClientCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.group.domain.Group;
|
||||
import org.mifosplatform.portfolio.group.domain.GroupRepository;
|
||||
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
|
||||
import org.mifosplatform.portfolio.note.domain.Note;
|
||||
import org.mifosplatform.portfolio.note.domain.NoteRepository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -44,37 +54,51 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
private final static Logger logger = LoggerFactory.getLogger(ClientWritePlatformServiceJpaRepositoryImpl.class);
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final ClientRepository clientRepository;
|
||||
private final ClientRepositoryWrapper clientRepository;
|
||||
private final OfficeRepository officeRepository;
|
||||
private final NoteRepository noteRepository;
|
||||
private final GroupRepository groupRepository;
|
||||
private final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||
private final ClientDataValidator fromApiJsonDeserializer;
|
||||
private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory;
|
||||
private final ConfigurationDomainService configurationDomainService;
|
||||
|
||||
@Autowired
|
||||
public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final ClientRepository clientRepository,
|
||||
final OfficeRepository officeRepository, final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
||||
final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final GroupRepository groupRepository) {
|
||||
public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
final ClientRepositoryWrapper clientRepository, final OfficeRepository officeRepository, final NoteRepository noteRepository,
|
||||
final ClientDataValidator fromApiJsonDeserializer,
|
||||
final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final GroupRepository groupRepository,
|
||||
final ConfigurationDomainService configurationDomainService) {
|
||||
this.context = context;
|
||||
this.clientRepository = clientRepository;
|
||||
this.officeRepository = officeRepository;
|
||||
this.noteRepository = noteRepository;
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory;
|
||||
this.groupRepository = groupRepository;
|
||||
this.configurationDomainService = configurationDomainService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult deleteClient(final Long clientId) {
|
||||
|
||||
final Client client = this.clientRepository.findOne(clientId);
|
||||
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); }
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
|
||||
final Long officeId = client.getOffice().getId();
|
||||
|
||||
client.delete();
|
||||
this.clientRepository.save(client);
|
||||
if (client.isNotPending()) { throw new ClientMustBePendingToBeDeletedException(clientId); }
|
||||
|
||||
return new CommandProcessingResultBuilder().withOfficeId(officeId).withClientId(clientId).withEntityId(clientId).build();
|
||||
List<Note> relatedNotes = this.noteRepository.findByClientId(clientId);
|
||||
this.noteRepository.deleteInBatch(relatedNotes);
|
||||
|
||||
// client.delete();
|
||||
this.clientRepository.delete(client);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withOfficeId(officeId) //
|
||||
.withClientId(clientId) //
|
||||
.withEntityId(clientId) //
|
||||
.build();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -107,23 +131,24 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
try {
|
||||
context.authenticatedUser();
|
||||
|
||||
this.fromApiJsonDeserializer.validateForCreate(command.json());
|
||||
final boolean isPendingApprovalEnabled = this.configurationDomainService.isClientPendingApprovalAllowedEnabled();
|
||||
this.fromApiJsonDeserializer.validateForCreate(command.json(), isPendingApprovalEnabled);
|
||||
|
||||
final Long officeId = command.longValueOfParameterNamed("officeId");
|
||||
final Long officeId = command.longValueOfParameterNamed(ClientApiConstants.officeIdParamName);
|
||||
|
||||
final Office clientOffice = this.officeRepository.findOne(officeId);
|
||||
if (clientOffice == null) { throw new OfficeNotFoundException(officeId); }
|
||||
|
||||
final Long groupId = command.longValueOfParameterNamed("groupId");
|
||||
final Long groupId = command.longValueOfParameterNamed(ClientApiConstants.groupIdParamName);
|
||||
|
||||
Group clientParentGroup = null;
|
||||
|
||||
if (groupId != null) {
|
||||
clientParentGroup = this.groupRepository.findOne(groupId);
|
||||
if (clientParentGroup == null) { throw new GroupNotFoundException(groupId); }
|
||||
}
|
||||
|
||||
final Client newClient = Client.fromJson(clientOffice, clientParentGroup, command);
|
||||
final Client newClient = Client.createNew(clientOffice, clientParentGroup, command, isPendingApprovalEnabled);
|
||||
|
||||
this.clientRepository.save(newClient);
|
||||
|
||||
if (newClient.isAccountNumberRequiresAutoGeneration()) {
|
||||
@@ -137,6 +162,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
.withCommandId(command.commandId()) //
|
||||
.withOfficeId(clientOffice.getId()) //
|
||||
.withClientId(newClient.getId()) //
|
||||
.withGroupId(groupId) //
|
||||
.withEntityId(newClient.getId()) //
|
||||
.build();
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
@@ -152,10 +178,10 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
try {
|
||||
context.authenticatedUser();
|
||||
|
||||
this.fromApiJsonDeserializer.validateForUpdate(command.json());
|
||||
final boolean isPendingApprovalEnabled = this.configurationDomainService.isClientPendingApprovalAllowedEnabled();
|
||||
this.fromApiJsonDeserializer.validateForUpdate(command.json(), isPendingApprovalEnabled);
|
||||
|
||||
final Client clientForUpdate = this.clientRepository.findOne(clientId);
|
||||
if (clientForUpdate == null || clientForUpdate.isDeleted()) { throw new ClientNotFoundException(clientId); }
|
||||
final Client clientForUpdate = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
|
||||
final Map<String, Object> changes = clientForUpdate.update(command);
|
||||
|
||||
@@ -173,7 +199,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withOfficeId(clientForUpdate.getOffice().getId()) //
|
||||
.withOfficeId(clientForUpdate.officeId()) //
|
||||
.withClientId(clientId) //
|
||||
.withEntityId(clientId) //
|
||||
.with(changes) //
|
||||
@@ -186,9 +212,37 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult saveOrUpdateClientImage(Long clientId, String imageName, InputStream inputStream) {
|
||||
public CommandProcessingResult activateClient(final Long clientId, final JsonCommand command) {
|
||||
try {
|
||||
final Client client = this.clientRepository.findOne(clientId);
|
||||
this.fromApiJsonDeserializer.validateActivation(command);
|
||||
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
|
||||
final Locale locale = command.extractLocale();
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
final LocalDate activationDate = command.localDateValueOfParameterNamed("activationDate");
|
||||
|
||||
client.activate(fmt, activationDate);
|
||||
|
||||
this.clientRepository.saveAndFlush(client);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withOfficeId(client.officeId()) //
|
||||
.withClientId(clientId) //
|
||||
.withEntityId(clientId) //
|
||||
.build();
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
handleDataIntegrityIssues(command, dve);
|
||||
return new CommandProcessingResult(Long.valueOf(-1));
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult saveOrUpdateClientImage(final Long clientId, final String imageName, final InputStream inputStream) {
|
||||
try {
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
String imageUploadLocation = setupForClientImageUpdate(clientId, client);
|
||||
|
||||
String imageLocation = FileUtils.saveToFileSystem(inputStream, imageUploadLocation, imageName);
|
||||
@@ -204,8 +258,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
@Override
|
||||
public CommandProcessingResult deleteClientImage(final Long clientId) {
|
||||
|
||||
final Client client = this.clientRepository.findOne(clientId);
|
||||
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); }
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
|
||||
// delete image from the file system
|
||||
if (StringUtils.isNotEmpty(client.getImageKey())) {
|
||||
@@ -217,7 +270,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
@Override
|
||||
public CommandProcessingResult saveOrUpdateClientImage(final Long clientId, final Base64EncodedImage encodedImage) {
|
||||
try {
|
||||
final Client client = this.clientRepository.findOne(clientId);
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
final String imageUploadLocation = setupForClientImageUpdate(clientId, client);
|
||||
|
||||
final String imageLocation = FileUtils.saveToFileSystem(encodedImage, imageUploadLocation, "image");
|
||||
@@ -255,5 +308,4 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) {
|
||||
logger.error(dve.getMessage(), dve);
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -252,7 +252,7 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
|
||||
}
|
||||
|
||||
Collection<ClientData> clientOptions = this.clientReadPlatformService
|
||||
.retrieveAllIndividualClientsForLookupByOfficeId(centerOfficeId);
|
||||
.retrieveAllForLookupByOfficeId(centerOfficeId);
|
||||
if (CollectionUtils.isEmpty(clientOptions)) {
|
||||
clientOptions = null;
|
||||
}
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
|
||||
}
|
||||
|
||||
Collection<ClientData> clientOptions = this.clientReadPlatformService
|
||||
.retrieveAllIndividualClientsForLookupByOfficeId(defaultOfficeId);
|
||||
.retrieveAllForLookupByOfficeId(defaultOfficeId);
|
||||
if (CollectionUtils.isEmpty(clientOptions)) {
|
||||
clientOptions = null;
|
||||
}
|
||||
|
||||
+20
-2
@@ -7,18 +7,28 @@ public class SearchParameters {
|
||||
private final String externalId;
|
||||
private final String name;
|
||||
private final String hierarchy;
|
||||
private final String firstname;
|
||||
private final String lastname;
|
||||
|
||||
public static SearchParameters from(final String sqlSearch, final Long officeId, final String externalId, final String name,
|
||||
final String hierarchy) {
|
||||
return new SearchParameters(sqlSearch, officeId, externalId, name, hierarchy);
|
||||
return new SearchParameters(sqlSearch, officeId, externalId, name, hierarchy, null, null);
|
||||
}
|
||||
|
||||
private SearchParameters(final String sqlSearch, final Long officeId, final String externalId, final String name, final String hierarchy) {
|
||||
public static SearchParameters forClients(final String sqlSearch, final Long officeId, final String externalId,
|
||||
final String displayName, final String firstname, final String lastname, final String hierarchy) {
|
||||
return new SearchParameters(sqlSearch, officeId, externalId, displayName, hierarchy, firstname, lastname);
|
||||
}
|
||||
|
||||
private SearchParameters(final String sqlSearch, final Long officeId, final String externalId, final String name,
|
||||
final String hierarchy, final String firstname, final String lastname) {
|
||||
this.sqlSearch = sqlSearch;
|
||||
this.officeId = officeId;
|
||||
this.externalId = externalId;
|
||||
this.name = name;
|
||||
this.hierarchy = hierarchy;
|
||||
this.firstname = firstname;
|
||||
this.lastname = lastname;
|
||||
}
|
||||
|
||||
public String getSqlSearch() {
|
||||
@@ -40,4 +50,12 @@ public class SearchParameters {
|
||||
public String getHierarchy() {
|
||||
return this.hierarchy;
|
||||
}
|
||||
|
||||
public String getFirstname() {
|
||||
return this.firstname;
|
||||
}
|
||||
|
||||
public String getLastname() {
|
||||
return this.lastname;
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -67,24 +67,24 @@ public class GuarantorData {
|
||||
allowedClientRelationshipTypes);
|
||||
}
|
||||
|
||||
public static GuarantorData mergeClientData(ClientData clientData, GuarantorData guarantorData) {
|
||||
public static GuarantorData mergeClientData(final ClientData clientData, final GuarantorData guarantorData) {
|
||||
return new GuarantorData(guarantorData.id, guarantorData.loanId, guarantorData.clientRelationshipType, guarantorData.entityId,
|
||||
guarantorData.guarantorType, clientData.getFirstname(), clientData.getLastname(), null, null, null, null, null, null, null,
|
||||
null, null, null, clientData.getOfficeName(), clientData.getJoinedDate(), clientData.getExternalId(), null,
|
||||
null, null, null, clientData.officeName(), clientData.getActivationDate(), clientData.getExternalId(), null,
|
||||
guarantorData.allowedClientRelationshipTypes);
|
||||
}
|
||||
|
||||
public static GuarantorData mergeStaffData(StaffData staffData, GuarantorData guarantorData) {
|
||||
public static GuarantorData mergeStaffData(final StaffData staffData, final GuarantorData guarantorData) {
|
||||
return new GuarantorData(guarantorData.id, guarantorData.loanId, guarantorData.clientRelationshipType, guarantorData.entityId,
|
||||
guarantorData.guarantorType, staffData.getFirstname(), staffData.getLastname(), null, null, null, null, null, null, null,
|
||||
null, null, null, staffData.getOfficeName(), null, null, null, guarantorData.allowedClientRelationshipTypes);
|
||||
}
|
||||
|
||||
public GuarantorData(Long id, Long loanId, final CodeValueData clientRelationshipType, Long entityId, EnumOptionData guarantorType,
|
||||
String firstname, String lastname, LocalDate dob, String addressLine1, String addressLine2, String city, String state,
|
||||
String zip, String country, String mobileNumber, String housePhoneNumber, String comment, String officeName,
|
||||
LocalDate joinedDate, String externalId, List<EnumOptionData> guarantorTypeOptions,
|
||||
Collection<CodeValueData> allowedClientRelationshipTypes) {
|
||||
public GuarantorData(final Long id, final Long loanId, final CodeValueData clientRelationshipType, final Long entityId, final EnumOptionData guarantorType,
|
||||
final String firstname, final String lastname, final LocalDate dob, final String addressLine1, final String addressLine2, final String city, final String state,
|
||||
final String zip, final String country, final String mobileNumber, final String housePhoneNumber, final String comment, final String officeName,
|
||||
final LocalDate joinedDate, final String externalId, final List<EnumOptionData> guarantorTypeOptions,
|
||||
final Collection<CodeValueData> allowedClientRelationshipTypes) {
|
||||
this.id = id;
|
||||
this.loanId = loanId;
|
||||
this.clientRelationshipType = clientRelationshipType;
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ public class GuarantorReadPlatformServiceImpl implements GuarantorReadPlatformSe
|
||||
*/
|
||||
private GuarantorData mergeDetailsForClientOrStaffGuarantor(GuarantorData guarantorData) {
|
||||
if (guarantorData.isExistingClient()) {
|
||||
ClientData clientData = clientReadPlatformService.retrieveIndividualClient(guarantorData.getEntityId());
|
||||
ClientData clientData = clientReadPlatformService.retrieveOne(guarantorData.getEntityId());
|
||||
return GuarantorData.mergeClientData(clientData, guarantorData);
|
||||
} else if (guarantorData.isStaffMember()) {
|
||||
StaffData staffData = staffReadPlatformService.retrieveStaff(guarantorData.getEntityId());
|
||||
|
||||
+8
-18
@@ -84,7 +84,7 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(guarantor.getOfficeId())
|
||||
.withEntityId(guarantor.getId()).withLoanId(loanId).build();
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
handleGuarantorDataIntegrityIssues(command, dve);
|
||||
handleGuarantorDataIntegrityIssues(dve);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(guarantorForUpdate.getOfficeId())
|
||||
.withEntityId(guarantorForUpdate.getId()).withOfficeId(guarantorForUpdate.getLoanId()).with(changesOnly).build();
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
handleGuarantorDataIntegrityIssues(command, dve);
|
||||
handleGuarantorDataIntegrityIssues(dve);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
@@ -142,32 +142,22 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto
|
||||
.withOfficeId(guarantorForDelete.getOfficeId()).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param loanId
|
||||
* @param loan
|
||||
* @param guarantor
|
||||
*/
|
||||
private void validateGuarantorBusinessRules(Guarantor guarantor) {
|
||||
private void validateGuarantorBusinessRules(final Guarantor guarantor) {
|
||||
// validate guarantor conditions
|
||||
if (guarantor.isExistingCustomer()) {
|
||||
// check client exists
|
||||
clientRepositoryWrapper.findOneWithNotFoundDetection(guarantor.getEntityId());
|
||||
// validate that the client is not set as a self guarantor
|
||||
if (guarantor.getClientId().equals(guarantor.getEntityId())) { throw new InvalidGuarantorException(guarantor.getEntityId(),
|
||||
guarantor.getLoanId()); }
|
||||
if (guarantor.getClientId().equals(guarantor.getEntityId())) {
|
||||
//
|
||||
throw new InvalidGuarantorException(guarantor.getEntityId(), guarantor.getLoanId());
|
||||
}
|
||||
} else if (guarantor.isExistingEmployee()) {
|
||||
staffRepositoryWrapper.findOneWithNotFoundDetection(guarantor.getEntityId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception for any data Integrity issue
|
||||
*
|
||||
* @param command
|
||||
* @param dve
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void handleGuarantorDataIntegrityIssues(final JsonCommand command, DataIntegrityViolationException dve) {
|
||||
private void handleGuarantorDataIntegrityIssues(final DataIntegrityViolationException dve) {
|
||||
Throwable realCause = dve.getMostSpecificCause();
|
||||
logger.error(dve.getMessage(), dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.guarantor.unknown.data.integrity.issue",
|
||||
|
||||
+3
-3
@@ -148,7 +148,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
|
||||
context.authenticatedUser();
|
||||
|
||||
final ClientData clientAccount = this.clientReadPlatformService.retrieveIndividualClient(clientId);
|
||||
final ClientData clientAccount = this.clientReadPlatformService.retrieveOne(clientId);
|
||||
final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant();
|
||||
LoanAccountData loanTemplateDetails = LoanAccountData.clientDefaults(clientAccount.id(), clientAccount.displayName(),
|
||||
clientAccount.officeId(), expectedDisbursementDate);
|
||||
@@ -666,14 +666,14 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
if (fromDate == null) {
|
||||
fromDate = this.lastDueDate;
|
||||
}
|
||||
final BigDecimal outstandingPrincipleBalanceOfLoan = outstandingLoanPrincipalBalance.subtract(principalDue);
|
||||
final BigDecimal outstandingPrincipalBalanceOfLoan = outstandingLoanPrincipalBalance.subtract(principalDue);
|
||||
|
||||
// update based on current period values
|
||||
this.lastDueDate = dueDate;
|
||||
outstandingLoanPrincipalBalance = outstandingLoanPrincipalBalance.subtract(principalDue);
|
||||
|
||||
final LoanSchedulePeriodData periodData = LoanSchedulePeriodData.repaymentPeriodWithPayments(loanId, period, fromDate,
|
||||
dueDate, principalDue, principalPaid, principalWrittenOff, principalOutstanding, outstandingPrincipleBalanceOfLoan,
|
||||
dueDate, principalDue, principalPaid, principalWrittenOff, principalOutstanding, outstandingPrincipalBalanceOfLoan,
|
||||
interestExpectedDue, interestPaid, interestWaived, interestWrittenOff, interestOutstanding, feeChargesExpectedDue,
|
||||
feeChargesPaid, feeChargesWaived, feeChargesWrittenOff, feeChargesOutstanding, penaltyChargesExpectedDue,
|
||||
penaltyChargesPaid, penaltyChargesWaived, penaltyChargesWrittenOff, penaltyChargesOutstanding, totalDueForPeriod,
|
||||
|
||||
+1
-1
@@ -147,7 +147,7 @@ public class LoanEnumerations {
|
||||
break;
|
||||
case EQUAL_PRINCIPAL:
|
||||
optionData = new EnumOptionData(AmortizationMethod.EQUAL_PRINCIPAL.getValue().longValue(),
|
||||
AmortizationMethod.EQUAL_PRINCIPAL.getCode(), "Equal principle payments");
|
||||
AmortizationMethod.EQUAL_PRINCIPAL.getCode(), "Equal principal payments");
|
||||
break;
|
||||
default:
|
||||
optionData = new EnumOptionData(AmortizationMethod.INVALID.getValue().longValue(), AmortizationMethod.INVALID.getCode(),
|
||||
|
||||
+5
-2
@@ -295,7 +295,10 @@ public class SavingsAccountDataValidator {
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
//
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||
dataValidationErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-2
@@ -82,7 +82,10 @@ public class SavingsAccountTransactionDataValidator {
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
//
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||
dataValidationErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -207,7 +207,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
|
||||
ClientData client = null;
|
||||
if (clientId != null) {
|
||||
client = this.clientReadPlatformService.retrieveIndividualClient(clientId);
|
||||
client = this.clientReadPlatformService.retrieveOne(clientId);
|
||||
}
|
||||
|
||||
GroupGeneralData group = null;
|
||||
|
||||
+2
-35
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
package org.mifosplatform.useradministration.api;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
@@ -22,23 +21,17 @@ import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.mifosplatform.commands.data.CommandSourceData;
|
||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||
import org.mifosplatform.commands.service.CommandWrapperBuilder;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandsReadPlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.useradministration.command.PermissionsCommand;
|
||||
import org.mifosplatform.useradministration.command.RoleCommand;
|
||||
import org.mifosplatform.useradministration.data.PermissionData;
|
||||
import org.mifosplatform.useradministration.data.RoleData;
|
||||
import org.mifosplatform.useradministration.data.RolePermissionsData;
|
||||
import org.mifosplatform.useradministration.serialization.PermissionsCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.useradministration.serialization.RoleCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.useradministration.service.PermissionReadPlatformService;
|
||||
import org.mifosplatform.useradministration.service.RoleReadPlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -67,33 +60,24 @@ public class RolesApiResource {
|
||||
private final PlatformSecurityContext context;
|
||||
private final RoleReadPlatformService roleReadPlatformService;
|
||||
private final PermissionReadPlatformService permissionReadPlatformService;
|
||||
private final RoleCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||
private final PermissionsCommandFromApiJsonDeserializer permissionsFromApiJsonDeserializer;
|
||||
private final DefaultToApiJsonSerializer<RoleData> toApiJsonSerializer;
|
||||
private final DefaultToApiJsonSerializer<RolePermissionsData> permissionsToApiJsonSerializer;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final PortfolioCommandsReadPlatformService commandSourceReadPlatformService;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public RolesApiResource(final PlatformSecurityContext context, final RoleReadPlatformService readPlatformService,
|
||||
final PermissionReadPlatformService permissionReadPlatformService,
|
||||
final RoleCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
||||
final PermissionsCommandFromApiJsonDeserializer permissionsFromApiJsonDeserializer,
|
||||
final DefaultToApiJsonSerializer<RoleData> toApiJsonSerializer,
|
||||
final DefaultToApiJsonSerializer<RolePermissionsData> permissionsToApiJsonSerializer,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final PortfolioCommandsReadPlatformService commandSourceReadPlatformService,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||
this.context = context;
|
||||
this.roleReadPlatformService = readPlatformService;
|
||||
this.permissionReadPlatformService = permissionReadPlatformService;
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
this.permissionsFromApiJsonDeserializer = permissionsFromApiJsonDeserializer;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.permissionsToApiJsonSerializer = permissionsToApiJsonSerializer;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.commandSourceReadPlatformService = commandSourceReadPlatformService;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
}
|
||||
|
||||
@@ -135,13 +119,7 @@ public class RolesApiResource {
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
RoleData role = this.roleReadPlatformService.retrieveOne(roleId);
|
||||
if (settings.isCommandIdPassed()) {
|
||||
final CommandSourceData entry = this.commandSourceReadPlatformService.retrieveById(settings.getCommandId());
|
||||
final RoleCommand changesOnly = this.fromApiJsonDeserializer.commandFromApiJson(entry.json());
|
||||
RoleData currentChanges = RoleData.changes(changesOnly.getName(), changesOnly.getDescription());
|
||||
role = RoleData.integrateChanges(role, currentChanges);
|
||||
}
|
||||
final RoleData role = this.roleReadPlatformService.retrieveOne(roleId);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(settings, role, RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
@@ -174,18 +152,7 @@ public class RolesApiResource {
|
||||
|
||||
final RoleData role = this.roleReadPlatformService.retrieveOne(roleId);
|
||||
final Collection<PermissionData> permissionUsageData = this.permissionReadPlatformService.retrieveAllRolePermissions(roleId);
|
||||
Collection<PermissionData> currentChanges = null;
|
||||
|
||||
if (settings.isCommandIdPassed()) {
|
||||
final CommandSourceData entry = this.commandSourceReadPlatformService.retrieveById(settings.getCommandId());
|
||||
PermissionsCommand command = permissionsFromApiJsonDeserializer.commandFromApiJson(entry.json());
|
||||
currentChanges = new ArrayList<PermissionData>();
|
||||
for (String key : command.getPermissions().keySet()) {
|
||||
currentChanges.add(PermissionData.from(key, command.getPermissions().get(key)));
|
||||
}
|
||||
}
|
||||
|
||||
final RolePermissionsData permissionsData = role.toRolePermissionData(permissionUsageData, currentChanges);
|
||||
final RolePermissionsData permissionsData = role.toRolePermissionData(permissionUsageData);
|
||||
return this.permissionsToApiJsonSerializer.serialize(settings, permissionsData, PERMISSIONS_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
|
||||
+3
-15
@@ -15,27 +15,15 @@ public class RoleData {
|
||||
private final Long id;
|
||||
private final String name;
|
||||
private final String description;
|
||||
@SuppressWarnings("unused")
|
||||
private final RoleData currentChanges;
|
||||
|
||||
public RolePermissionsData toRolePermissionData(final Collection<PermissionData> permissionUsageData,
|
||||
final Collection<PermissionData> currentChanges) {
|
||||
return new RolePermissionsData(id, name, description, permissionUsageData, currentChanges);
|
||||
public RolePermissionsData toRolePermissionData(final Collection<PermissionData> permissionUsageData) {
|
||||
return new RolePermissionsData(id, name, description, permissionUsageData);
|
||||
}
|
||||
|
||||
public static RoleData changes(final String name, final String description) {
|
||||
return new RoleData(null, name, description, null);
|
||||
}
|
||||
|
||||
public static RoleData integrateChanges(final RoleData role, final RoleData currentChanges) {
|
||||
return new RoleData(role.id, role.name, role.description, currentChanges);
|
||||
}
|
||||
|
||||
public RoleData(final Long id, final String name, final String description, final RoleData currentChanges) {
|
||||
public RoleData(final Long id, final String name, final String description) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.currentChanges = currentChanges;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-4
@@ -21,15 +21,12 @@ public class RolePermissionsData {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<PermissionData> permissionUsageData;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<PermissionData> currentChanges;
|
||||
|
||||
public RolePermissionsData(final Long id, final String name, final String description,
|
||||
final Collection<PermissionData> permissionUsageData, final Collection<PermissionData> currentChanges) {
|
||||
final Collection<PermissionData> permissionUsageData) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.permissionUsageData = permissionUsageData;
|
||||
this.currentChanges = currentChanges;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -36,7 +36,7 @@ public class Role extends AbstractPersistable<Long> {
|
||||
|
||||
@ManyToMany(fetch = FetchType.EAGER)
|
||||
@JoinTable(name = "m_role_permission", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "permission_id"))
|
||||
private Set<Permission> permissions = new HashSet<Permission>();
|
||||
private final Set<Permission> permissions = new HashSet<Permission>();
|
||||
|
||||
public static Role fromJson(final JsonCommand command) {
|
||||
final String name = command.stringValueOfParameterNamed("name");
|
||||
@@ -109,6 +109,6 @@ public class Role extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public RoleData toData() {
|
||||
return new RoleData(this.getId(), this.name, this.description, null);
|
||||
return new RoleData(this.getId(), this.name, this.description);
|
||||
}
|
||||
}
|
||||
+7
-25
@@ -18,21 +18,15 @@ 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.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.useradministration.command.RoleCommand;
|
||||
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 RoleCommand}'s.
|
||||
*/
|
||||
@Component
|
||||
public final class RoleCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<RoleCommand> {
|
||||
public final class RoleCommandValidator {
|
||||
|
||||
/**
|
||||
* The parameters supported for this command.
|
||||
@@ -42,25 +36,10 @@ public final class RoleCommandFromApiJsonDeserializer extends AbstractFromApiJso
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public RoleCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
|
||||
public RoleCommandValidator(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleCommand commandFromApiJson(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 JsonElement element = fromApiJsonHelper.parse(json);
|
||||
final String name = fromApiJsonHelper.extractStringNamed("name", element);
|
||||
final String description = fromApiJsonHelper.extractStringNamed("description", element);
|
||||
|
||||
return new RoleCommand(name, description);
|
||||
}
|
||||
|
||||
public void validateForCreate(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
@@ -106,7 +85,10 @@ public final class RoleCommandFromApiJsonDeserializer extends AbstractFromApiJso
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
//
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||
dataValidationErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class RoleReadPlatformServiceImpl implements RoleReadPlatformService {
|
||||
final String name = rs.getString("name");
|
||||
final String description = rs.getString("description");
|
||||
|
||||
return new RoleData(id, name, description, null);
|
||||
return new RoleData(id, name, description);
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ import org.mifosplatform.useradministration.domain.RoleRepository;
|
||||
import org.mifosplatform.useradministration.exception.PermissionNotFoundException;
|
||||
import org.mifosplatform.useradministration.exception.RoleNotFoundException;
|
||||
import org.mifosplatform.useradministration.serialization.PermissionsCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.useradministration.serialization.RoleCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.useradministration.serialization.RoleCommandValidator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -37,12 +37,12 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf
|
||||
private final PlatformSecurityContext context;
|
||||
private final RoleRepository roleRepository;
|
||||
private final PermissionRepository permissionRepository;
|
||||
private final RoleCommandFromApiJsonDeserializer roleCommandFromApiJsonDeserializer;
|
||||
private final RoleCommandValidator roleCommandFromApiJsonDeserializer;
|
||||
private final PermissionsCommandFromApiJsonDeserializer permissionsFromApiJsonDeserializer;
|
||||
|
||||
@Autowired
|
||||
public RoleWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final RoleRepository roleRepository,
|
||||
final PermissionRepository permissionRepository, final RoleCommandFromApiJsonDeserializer roleCommandFromApiJsonDeserializer,
|
||||
final PermissionRepository permissionRepository, final RoleCommandValidator roleCommandFromApiJsonDeserializer,
|
||||
final PermissionsCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
|
||||
this.context = context;
|
||||
this.roleRepository = roleRepository;
|
||||
|
||||
Reference in New Issue
Block a user