diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm
index 7bee3c5f0..31cad5e87 100644
--- a/api-docs/apiLive.htm
+++ b/api-docs/apiLive.htm
@@ -176,6 +176,14 @@
|
Retrieve a Client |
Update a Client |
+ Delete a Client |
+
+
+ |
+ clients/{clientId}?command=activate |
+ Activate a Client |
+ |
+ |
|
@@ -1697,8 +1705,8 @@ function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFuncti
Clients
-
Clients are people and businesses that have applied (or may
- apply) to an MFI for loans.
+
Clients are people and businesses that have applied (or may apply) to an MFI for loans.
+
Clients can be created in Pending state (as opposed to Active state) if global configuration for allow-pending-client-status is enabled.
Field Descriptions |
@@ -1712,6 +1720,29 @@ function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFuncti
auto generated account no. is put in place based on the
configured strategy.
+
+ | externalId |
+
+
+ A place to put an external reference for
+ this client e.g. The ID another system uses. If
+ provided, it must be unique.
+ |
+
+
+ | active |
+
+
+ | Indicates whether this client is to be created as active client. If active=true, then activationDate must be provided. If active=false, then the client is created as pending but this must be allowed through configuration.
+ |
+
+
+ | activationDate |
+
+
+ | The date on which the client became active.
+ |
+
| firstname |
@@ -1741,63 +1772,11 @@ function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFuncti
business that doesnt suit the firstname,middlename,lastname
structure.
-
- | externalId |
-
-
- A place to put an external reference for
- this client e.g. The ID another system uses. If
- provided, it must be unique.
- |
-
-
-
-
-
List Clients
-
Example Requests:
-
clients
-
-
-
clients?fields=displayName,officeName,joinedDate
-
-
-
-GET https://DomainName/api/v1/clients
-
-
-[
- {
- "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]
- }
-]
-
-
-
-
-
+
Retrieve Client Details Template
@@ -1819,58 +1798,20 @@ GET https://DomainName/api/v1/clients/template
{
- "officeId": 1,
- "joinedDate": [
- 2013,
- 2,
- 5
- ],
- "allowedOffices": [
- {
- "id": 1,
- "name": "Head Office",
- "nameDecorated": "Head Office"
- }
- ]
-}
-
-
-
-
-
-
-
-
-
Retrieve a Client
-
Example Requests:
-
clients/1
-
-
-
clients/1?template=true
-
-
-
clients/1?fields=id,displayName,officeName
-
-
-
-GET https://DomainName/api/v1/clients/{clientId}
-
-
-{
- "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"
+ }
+ ]
}
@@ -1891,11 +1832,19 @@ GET https://DomainName/api/v1/clients/{clientId}
Mandatory Fields |
- firstname and lastname OR fullname , joinedDate,
- officeId
+ | firstname and lastname OR fullname, officeId, active=true and activationDate OR active=false,
|
+
+
+
+ Optional Fields |
+
+
+ | groupId, externalId, accountNo |
+
+
@@ -1904,14 +1853,15 @@ POST https://DomainName/api/v1/clients
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"
}
@@ -1926,30 +1876,166 @@ Content-Type: application/json Request Body:
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"
}
{
- "officeId": 1,
- "clientId": 2,
- "resourceId": 2
+ "officeId": 1,
+ "groupId": 1,
+ "clientId": 2,
+ "resourceId": 2
}
+
+
+
+
Activate a Client
+
Clients can be created in a Pending state if configuration is enabled. This API exists to enable client activation (for when a client becomes approved member of microfinance institue.
+
If the client happens to be alrady active this API will result in an error.
+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=activate
+ POST clients/1?command=activate
+Content-Type: application/json
+Request Body:
+{
+ "locale": "en",
+ "dateFormat": "dd MMMM yyyy",
+ "activationDate": "01 March 2011"
+}
+
+
+{
+ "officeId": 1,
+ "clientId": 1,
+ "resourceId": 1
+}
+
+
+
+
+
+
+
+
Retrieve a Client
+
Example Requests:
+
clients/1
+
+
+
clients/1?template=true
+
+
+
clients/1?fields=id,displayName,officeName
+
+
+
+GET https://DomainName/api/v1/clients/{clientId}
+
+
+{
+ "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"
+ }
+ ]
+}
+
+
+
+
+
+
+
+
List Clients
+
Example Requests:
+
clients
+
+
+
clients?fields=displayName,officeName,joinedDate
+
+
+
+GET https://DomainName/api/v1/clients
+
+
+[
+ {
+ "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"
+ }
+]
+
+
+
+
Update a Client
+
You can update any attribute of a client except for its association with groups. The relationship between a client and a group must be removed through the Groups API.
@@ -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"
}
@@ -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"
}
}
-
+
+
+
+
Delete a Client
+
If a client is in Pending state you are allowed to Delete 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 Close the client if they have died or exited the program.
+
+
+
+DELETE https://DomainName/api/v1/clients/{clientId}
+
+
+DELETE clients/3
+Content-Type: application/json
+Request Body:
+{
+}
+
+
+{
+ "officeId": 1,
+ "clientId": 3,
+ "resourceId": 3
+}
+
+
+
+
+
Retrieve a Client's Loan Account Summary
@@ -7066,13 +7172,16 @@ Request Body:
Global Configuration
-
Global configuration related to set of supported
- enable/disable configurations e.g. maker-checker.
+
Global configuration related to set of supported enable/disable configurations:
+
+ - maker-checker - defaults to false - if true turns on maker-checker functionality
+ - allow-pending-client-status - defaults to false - if true allows clients to be created in 'Pending' state
+ - allow-pending-group-status - defaults to false - if true allows groups to be created in 'Pending' state
+
-
+
Retrieve Global Configuration
@@ -7086,12 +7195,20 @@ GET https://DomainName/api/v1/configurations
{
- "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
+ }
+ ]
}
@@ -7105,14 +7222,22 @@ GET https://DomainName/api/v1/configurations
-PUT https://DomainName/api/v1/configurations?maker-checker=false
+PUT https://DomainName/api/v1/configurations?allow-pending-client-status=false
PUT configurations
Content-Type: application/json
Request Body: { }
- { "changes": {} }
+
+{
+ "changes": {
+ "globalConfiguration": {
+ "allow-pending-client-status": false
+ }
+ }
+}
+
@@ -12884,6 +13009,14 @@ GET https://DomainName/api/v1/search?query=000000111
|
Retrieve a Client |
Update a Client |
+
Delete a Client |
+
+
+ |
+ clients/{clientId}?command=activate |
+ Activate a Client |
+ |
+ |
|
diff --git a/mifosng-db/migrations/core_db/V21__activation-permissions-for-clients.sql b/mifosng-db/migrations/core_db/V21__activation-permissions-for-clients.sql
new file mode 100644
index 000000000..c42f2a555
--- /dev/null
+++ b/mifosng-db/migrations/core_db/V21__activation-permissions-for-clients.sql
@@ -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`;
\ No newline at end of file
diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/AccountingScenario.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/AccountingScenario.java
index 5922366bb..1d65ee261 100644
--- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/AccountingScenario.java
+++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/AccountingScenario.java
@@ -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);
diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/LoanWithWaiveInterestAndWriteOffIntegrationTest.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/LoanWithWaiveInterestAndWriteOffIntegrationTest.java
index 47f823743..e2200f7a9 100644
--- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/LoanWithWaiveInterestAndWriteOffIntegrationTest.java
+++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/LoanWithWaiveInterestAndWriteOffIntegrationTest.java
@@ -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);
}
diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/LoanWithdrawnByApplicant.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/LoanWithdrawnByApplicant.java
index aec47a7da..eae6b42d7 100644
--- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/LoanWithdrawnByApplicant.java
+++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/LoanWithdrawnByApplicant.java
@@ -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);
}
}
diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/accounting/GLAccountBuilder.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/accounting/GLAccountBuilder.java
index b005716e7..83c468a65 100644
--- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/accounting/GLAccountBuilder.java
+++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/accounting/GLAccountBuilder.java
@@ -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 map = new HashMap();
- 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;
}
}
diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/accounting/JournalEntryHelper.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/accounting/JournalEntryHelper.java
index 068ac4628..b7fc9fdca 100644
--- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/accounting/JournalEntryHelper.java
+++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/accounting/JournalEntryHelper.java
@@ -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 entryResponse, int entryNumber) {
+ private String getEntryValueFromJournalEntry(final ArrayList entryResponse, final int entryNumber) {
HashMap map = (HashMap) entryResponse.get(entryNumber).get("entryType");
return (String) map.get("value");
}
- private Float getTransactionAmountFromJournalEntry(ArrayList entryResponse, int entryNumber) {
+ private Float getTransactionAmountFromJournalEntry(final ArrayList 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 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");
}
diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanApplicationTestBuilder.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanApplicationTestBuilder.java
index 7f1c29582..5bf85ef72 100644
--- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanApplicationTestBuilder.java
+++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanApplicationTestBuilder.java
@@ -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;
}
diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanProductTestBuilder.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanProductTestBuilder.java
index 15a29c0de..f815f5676 100644
--- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanProductTestBuilder.java
+++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanProductTestBuilder.java
@@ -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;
}
diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanTransactionHelper.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanTransactionHelper.java
index a1bf5ea81..e54b09282 100644
--- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanTransactionHelper.java
+++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanTransactionHelper.java
@@ -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 repaymentPeriods = getLoanRepaymentSchedule(requestSpec, responseSpec, loanID);
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
index 084d661f0..57dae8a6f 100755
--- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
@@ -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,
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/api/MakercheckersApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/api/MakercheckersApiResource.java
index 8c47d705c..061907a8e 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/commands/api/MakercheckersApiResource.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/api/MakercheckersApiResource.java
@@ -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 RESPONSE_DATA_PARAMETERS = new HashSet(
- 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 RESPONSE_DATA_PARAMETERS = new HashSet(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 toApiJsonSerializer;
- private final DefaultToApiJsonSerializer toApiJsonSerializerAudit;
- private final DefaultToApiJsonSerializer toApiJsonSerializerSearchTemplate;
- private final ApiRequestParameterHelper apiRequestParameterHelper;
- private final PortfolioCommandSourceWritePlatformService writePlatformService;
+ private final AuditReadPlatformService readPlatformService;
+ private final DefaultToApiJsonSerializer toApiJsonSerializerAudit;
+ private final DefaultToApiJsonSerializer toApiJsonSerializerSearchTemplate;
+ private final ApiRequestParameterHelper apiRequestParameterHelper;
+ private final PortfolioCommandSourceWritePlatformService writePlatformService;
- @Autowired
- public MakercheckersApiResource(
- final AuditReadPlatformService readPlatformService,
- final DefaultToApiJsonSerializer toApiJsonSerializer,
- final DefaultToApiJsonSerializer toApiJsonSerializerAudit,
- final DefaultToApiJsonSerializer 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 toApiJsonSerializerAudit,
+ final DefaultToApiJsonSerializer 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 entries = this.readPlatformService
- .retrieveAllEntriesToBeChecked(extraCriteria,
- settings.isIncludeJson());
+ final Collection 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 RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE = new HashSet(
- Arrays.asList("appUsers", "actionNames", "entityNames"));
+ final Set RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE = new HashSet(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;
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/data/CommandSourceData.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/data/CommandSourceData.java
index 0e2875c11..402a60cd2 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/commands/data/CommandSourceData.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/data/CommandSourceData.java
@@ -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;
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java
index 44b6c1140..0fb231e2a 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java
@@ -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");
}
-
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java
index 8fed138eb..434ba0983 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java
@@ -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;
- }
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandsReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandsReadPlatformService.java
deleted file mode 100644
index def300550..000000000
--- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandsReadPlatformService.java
+++ /dev/null
@@ -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 retrieveUnprocessChangesByEntityNameAndId(String entityName, Long entityId);
-}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandsReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandsReadPlatformServiceImpl.java
deleted file mode 100644
index 1a6279b54..000000000
--- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandsReadPlatformServiceImpl.java
+++ /dev/null
@@ -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 {
-
- 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 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 });
- }
-}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java
index f98d0f464..2a8003cce 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java
@@ -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()) {
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java
index c6b9d1c8b..4f3e775dc 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java
@@ -9,4 +9,5 @@ public interface ConfigurationDomainService {
boolean isMakerCheckerEnabledForTask(String taskPermissionCode);
-}
+ boolean isClientPendingApprovalAllowedEnabled();
+}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
index 110c66b42..03c03079a 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
@@ -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();
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/ApiRequestParameterHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/ApiRequestParameterHelper.java
index 81262c71b..b73492ee0 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/ApiRequestParameterHelper.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/ApiRequestParameterHelper.java
@@ -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 queryParameters) {
@@ -48,11 +46,9 @@ public class ApiRequestParameterHelper {
final Set 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);
}
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/DataValidatorBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/DataValidatorBuilder.java
index 48449c38a..8162cb0d5 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/DataValidatorBuilder.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/DataValidatorBuilder.java
@@ -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;
- }
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/serialization/ApiRequestJsonSerializationSettings.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/serialization/ApiRequestJsonSerializationSettings.java
index d46fcc2c1..ea6253f96 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/serialization/ApiRequestJsonSerializationSettings.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/serialization/ApiRequestJsonSerializationSettings.java
@@ -16,28 +16,25 @@ public class ApiRequestJsonSerializationSettings {
private final boolean prettyPrint;
private final Set parametersForPartialResponse;
private final boolean template;
- private final Long commandId;
private final boolean makerCheckerable;
private final boolean includeJson;
public ApiRequestJsonSerializationSettings(final boolean prettyPrint, final Set 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 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 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;
- }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/office/data/OfficeLookup.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/office/data/OfficeLookup.java
index 775dc912c..8ff0cf2e3 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/office/data/OfficeLookup.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/office/data/OfficeLookup.java
@@ -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;
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/office/service/OfficeReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/office/service/OfficeReadPlatformService.java
index 8e584986b..e6b83dd8c 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/office/service/OfficeReadPlatformService.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/office/service/OfficeReadPlatformService.java
@@ -21,6 +21,7 @@ public interface OfficeReadPlatformService {
* Deprecated so cane eventually remove need for OfficeLookup type - so use
* retrieveAllOfficesForDropdown instead.
*/
+ @Deprecated
Collection retrieveAllOfficesForLookup();
OfficeData retrieveOffice(Long officeId);
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientApiConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientApiConstants.java
new file mode 100644
index 000000000..880478375
--- /dev/null
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientApiConstants.java
@@ -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 CLIENT_REQUEST_DATA_PARAMETERS = new HashSet(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 CLIENT_RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList(idParamName, accountNoParamName,
+ externalIdParamName, statusParamName, firstnameParamName, middlenameParamName, lastnameParamName, fullnameParamName,
+ displayNameParamName, officeIdParamName, officeNameParamName, staffIdParamName, staffNameParamName, hierarchyParamName,
+ officeOptionsParamName, staffOptionsParamName));
+
+ public static final Set ACTIVATION_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList(localeParamName,
+ dateFormatParamName, activationDateParamName));
+}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientImagesApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientImagesApiResource.java
index 8c7ea0736..dccf49f26 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientImagesApiResource.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientImagesApiResource.java
@@ -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); }
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java
index 487920348..2727f61b9 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java
@@ -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 CLIENT_DATA_PARAMETERS = new HashSet(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 toApiJsonSerializer;
private final ToApiJsonSerializer 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 toApiJsonSerializer,
- final ClientCommandFromApiJsonDeserializer clientCommandFromApiJsonDeserializer,
final ToApiJsonSerializer 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 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 allowedOffices = new ArrayList(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 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 dataChanges = null; // retrieveAllUnprocessedDataChanges(clientId);
- return ClientData.integrateChanges(clientData, currentChange, dataChanges);
- }
-
- private Collection retrieveAllUnprocessedDataChanges(final Long clientId) {
- Collection dataChanges = new ArrayList();
-
- Collection 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 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 allowedOffices = new ArrayList(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 CLIENT_ACCOUNTS_DATA_PARAMETERS = new HashSet(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);
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java
index 99b0ec534..1126638fa 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java
@@ -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 {
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 parentGroups;
+ private final Collection groups;
// template
- private final List allowedOffices;
- private final ClientData currentChange;
- private final Collection allChanges;
+ private final Collection 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 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 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 allowedOffices) {
- public static ClientData template(final Long officeId, final LocalDate joinedDate, final List 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 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 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 allowedOffices, final ClientData currentChange,
- final Collection allChanges, final Collection 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 allowedOffices, final Collection 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 {
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 {
.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 {
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;
}
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java
new file mode 100644
index 000000000..cd87eb052
--- /dev/null
+++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java
@@ -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