update api-docs and loan functionality from api.
This commit is contained in:
+199
-185
@@ -327,7 +327,7 @@ function getBaseURL(docURL)
|
||||
<div class="tocMatrix">
|
||||
<table class=matrixHeading>
|
||||
<tr class="matrixHeadingBG"><td colspan=2 valign="top"><div class="matrixHeadingVerbs"><table><tr><td>RESOURCES</td></tr></table></div></td><td><table><tr><td><div class="matrixHeadingVerbs">POST</div></td></tr><tr><td><div class=matrixHeadingCommands>create/complex update</div></td></tr></table></td><td><table><tr><td><div class="matrixHeadingVerbs">GET</div></td></tr><tr><td><div class=matrixHeadingCommands>read</div></td></tr></table></td><td><table><tr><td><div class="matrixHeadingVerbs">PUT</div></td></tr><tr><td><div class=matrixHeadingCommands>update</div></td></tr></table></td><td><table><tr><td><div class="matrixHeadingVerbs">DELETE</div></td></tr><tr><td><div class=matrixHeadingCommands>delete</div></td></tr></table></td></tr>
|
||||
<tr><td><a href="#authentication">AUTHENTICATION</a></td><td>authentication</td><td><a href="#authentication_permissions">Verify Authentication</a></td><td></td><td></td><td></td></tr>
|
||||
<tr><td><a href="#authentication">AUTHENTICATION</a></td><td>authentication</td><td><a href="#authenticate_request">Verify Authentication</a></td><td></td><td></td><td></td></tr>
|
||||
<tr class="alt"><td><a href="#users">USER</a></td><td>users</td><td><a href="#users_create">Create a User</a></td><td><a href="#users_list">List Users</a></td><td></td><td></td></tr>
|
||||
<tr><td></td><td>users/{userId}</td><td></td><td><a href="#users_retrieve">Retrieve a User</a></td><td><a href="#users_update">Update a User</a></td><td><a href="#users_delete">Delete a User</a></td></tr>
|
||||
<tr class="alt"><td><a href="#roles">ROLE</a></td><td>roles</td><td><a href="#roles_create">Create a New Role</a></td><td><a href="#roles_list">List Roles</a></td><td></td><td></td></tr>
|
||||
@@ -634,9 +634,6 @@ var jqxhr = $.ajax({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- start of clients api docs -->
|
||||
<a id="clients" name="clients" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
@@ -673,26 +670,37 @@ var jqxhr = $.ajax({
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/clients</code>
|
||||
<code class="method-response">[ {
|
||||
"id" : 14,
|
||||
"accountNo": "14",
|
||||
"firstname" : "Patrick",
|
||||
"middlename" : "J"
|
||||
"lastname" : "Asare-Frimpong",
|
||||
"displayName" : "Patrick J Asare-Frimpong",
|
||||
"officeId" : 2,
|
||||
"officeName" : "sub branch 1",
|
||||
"externalId" : "123AB",
|
||||
"joinedDate" : [ 2012, 4, 18 ]
|
||||
}, {
|
||||
"id" : 13,
|
||||
"accountNo": "0000000AB5",
|
||||
"fullname" : "My micro business Ltd."
|
||||
"displayName" : "My micro business Ltd.",
|
||||
"officeId" : 5,
|
||||
"officeName" : "Majmoua",
|
||||
"joinedDate" : [ 2011, 12, 1 ]
|
||||
}... ]
|
||||
<code class="method-response">[
|
||||
{
|
||||
"id": 2,
|
||||
"accountNo": "000000002",
|
||||
"externalId": "one/78",
|
||||
"fullname": "New Business to Create",
|
||||
"displayName": "New Business to Create",
|
||||
"officeId": 1,
|
||||
"officeName": "Head Office",
|
||||
"joinedDate": [
|
||||
2006,
|
||||
6,
|
||||
13
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"accountNo": "000000001",
|
||||
"externalId": "786YYH7",
|
||||
"firstname": "Petra",
|
||||
"lastname": "Yton",
|
||||
"displayName": "Petra Yton",
|
||||
"officeId": 1,
|
||||
"officeName": "Head Office",
|
||||
"joinedDate": [
|
||||
2009,
|
||||
3,
|
||||
4
|
||||
]
|
||||
}
|
||||
]
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
@@ -713,23 +721,15 @@ var jqxhr = $.ajax({
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/clients/template</code>
|
||||
<code class="method-response">{
|
||||
"joinedDate" : [ 2012, 5, 29 ],
|
||||
"allowedOffices" : [ {
|
||||
"id" : 1,
|
||||
"name" : "Demo MFI Head Office"
|
||||
}, {
|
||||
"id" : 2,
|
||||
"name" : "sub branch 1"
|
||||
}, {
|
||||
"id" : 8,
|
||||
"name" : "moi aussi"
|
||||
}, {
|
||||
"id" : 3,
|
||||
"name" : "sub branch 2"
|
||||
}, {
|
||||
"id" : 4,
|
||||
"name" : "sub branch 3"
|
||||
} ]
|
||||
"officeId": 1,
|
||||
"joinedDate": [ 2013, 2, 5],
|
||||
"allowedOffices": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Head Office",
|
||||
"nameDecorated": "Head Office"
|
||||
}
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -750,13 +750,19 @@ var jqxhr = $.ajax({
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/clients/{clientId}</code>
|
||||
<code class="method-response">{
|
||||
"id" : 1,
|
||||
"firstname" : "Patrick",
|
||||
"lastname" : "O'Meara",
|
||||
"displayName" : "Patrick O'Meara",
|
||||
"officeId" : 1,
|
||||
"officeName" : "Demo MFI Head Office",
|
||||
"joinedDate" : [ 2009, 1, 4 ]
|
||||
"id": 1,
|
||||
"accountNo": "000000001",
|
||||
"externalId": "786YYH7",
|
||||
"firstname": "Petra",
|
||||
"lastname": "Yton",
|
||||
"displayName": "Petra Yton",
|
||||
"officeId": 1,
|
||||
"officeName": "Head Office",
|
||||
"joinedDate": [
|
||||
2009,
|
||||
3,
|
||||
4
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -792,8 +798,8 @@ Request Body:
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"officeId": 1,
|
||||
"clientId": 83,
|
||||
"resourceId": 83
|
||||
"clientId": 1,
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -812,8 +818,8 @@ Request Body:
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"officeId": 1,
|
||||
"clientId": 84,
|
||||
"resourceId": 84
|
||||
"clientId": 2,
|
||||
"resourceId": 2
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -826,7 +832,7 @@ Request Body:
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">PUT https://Domain Name/api/v1/clients/{clientId}</code>
|
||||
<code class="method-request">PUT clients/83
|
||||
<code class="method-request">PUT clients/1
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
@@ -838,8 +844,8 @@ Request Body:
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"officeId": 1,
|
||||
"clientId": 83,
|
||||
"resourceId": 83,
|
||||
"clientId": 1,
|
||||
"resourceId": 1,
|
||||
"changes": {
|
||||
"externalId": "786444UUUYYH7",
|
||||
"joinedDate": "09 June 2006",
|
||||
@@ -1389,30 +1395,29 @@ Request Body:
|
||||
<br><br>
|
||||
<div class=apiClick>loans/1?associations=all</div>
|
||||
<br><br>
|
||||
<div class=apiClick>loans/1?fields=id,principal,annualInterestRate&associations=summary,repaymentSchedule</div>
|
||||
<div class=apiClick>loans/1?fields=id,principal,annualInterestRate&associations=repaymentSchedule,transactions</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/loans/{loanId}</code>
|
||||
<code class="method-response">{
|
||||
{
|
||||
"id": 1,
|
||||
"accountNo": "000000001",
|
||||
"clientId": 1,
|
||||
"clientName": "Willie O'Meara",
|
||||
"clientName": "Petra Yton",
|
||||
"loanProductId": 1,
|
||||
"loanProductName": "Agricultural Loan",
|
||||
"loanProductDescription": "An agricultural loan given to farmers to help buy crop, stock and machinery. With an arrears tolerance setting of 1,000 CFA, loans are not marked as 'in arrears' or 'in bad standing' if the amount outstanding is less than this. Interest rate is described using monthly percentage rate (MPR) even though the loan typically lasts a year and requires one repayment (typically at time when farmer sells crop)",
|
||||
"loanProductName": "A new loan product for me",
|
||||
"status": {
|
||||
"id": 100,
|
||||
"code": "loanStatusType.submitted.and.pending.approval",
|
||||
"value": "Submitted and pending approval"
|
||||
},
|
||||
"currency": {
|
||||
"code": "XOF",
|
||||
"name": "CFA Franc BCEAO",
|
||||
"decimalPlaces": 0,
|
||||
"displaySymbol": "CFA",
|
||||
"nameCode": "currency.XOF",
|
||||
"displayLabel": "CFA Franc BCEAO (CFA)"
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"displaySymbol": "$",
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"principal": 100000,
|
||||
"termFrequency": 12,
|
||||
@@ -1509,7 +1514,10 @@ Request Body:
|
||||
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 42
|
||||
"officeId": 1,
|
||||
"clientId": 1,
|
||||
"loanId": 1,
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -1542,13 +1550,28 @@ Request Body:
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"eventDate": "07 May 2012",
|
||||
"note": "and event note is added"
|
||||
} </code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"resourceId": 37
|
||||
"locale": "en",
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"eventDate": "20 September 2011",
|
||||
"note": "and event note is added"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"officeId": 1,
|
||||
"clientId": 1,
|
||||
"loanId": 2,
|
||||
"resourceId": 2,
|
||||
"changes": {
|
||||
"status": {
|
||||
"id": 200,
|
||||
"code": "loanStatusType.approved",
|
||||
"value": "Approved"
|
||||
},
|
||||
"locale": "en",
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"approvedOnDate": "20 September 2011",
|
||||
"note": "and event note is added"
|
||||
}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -1568,7 +1591,10 @@ Content-Type: application/json
|
||||
No Request Body:
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 1
|
||||
"officeId": 1,
|
||||
"clientId": 1,
|
||||
"loanId": 1,
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -1749,27 +1775,20 @@ Request Body:
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/offices</code>
|
||||
<code class="method-response">[ {
|
||||
"id" : 1,
|
||||
"name" : "Demo MFI Head Office",
|
||||
"externalId" : "1",
|
||||
"openingDate" : [ 2009, 1, 1 ],
|
||||
"hierarchy" : "."
|
||||
}, {
|
||||
"id" : 2,
|
||||
"name" : "B1",
|
||||
"openingDate" : [ 2012, 4, 1 ],
|
||||
"hierarchy" : ".2.",
|
||||
"parentName" : "Demo MFI Head Office",
|
||||
"parentId" : 1
|
||||
}, {
|
||||
"id" : 3,
|
||||
"name" : "B2",
|
||||
"openingDate" : [ 2012, 4, 4 ],
|
||||
"hierarchy" : ".3.",
|
||||
"parentName" : "Demo MFI Head Office",
|
||||
"parentId" : 1
|
||||
} ]
|
||||
<code class="method-response">[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Head Office",
|
||||
"nameDecorated": "Head Office",
|
||||
"externalId": "1",
|
||||
"openingDate": [
|
||||
2009,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"hierarchy": "."
|
||||
}
|
||||
]
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1790,17 +1809,14 @@ Request Body:
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/offices/template</code>
|
||||
<code class="method-response">{
|
||||
"openingDate" : [ 2012, 5, 28 ],
|
||||
"allowedParents" : [ {
|
||||
"id" : 1,
|
||||
"name" : "Demo MFI Head Office"
|
||||
}, {
|
||||
"id" : 2,
|
||||
"name" : "B1"
|
||||
}, {
|
||||
"id" : 3,
|
||||
"name" : "B2"
|
||||
} ]
|
||||
"openingDate": [2013,2,4],
|
||||
"allowedParents": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Head Office",
|
||||
"nameDecorated": "Head Office"
|
||||
}
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -1820,11 +1836,12 @@ Request Body:
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/offices/1</code>
|
||||
<code class="method-response">{
|
||||
"id" : 1,
|
||||
"name" : "Demo MFI Head Office",
|
||||
"externalId" : "1",
|
||||
"openingDate" : [ 2009, 1, 1 ],
|
||||
"hierarchy" : "."
|
||||
"id": 1,
|
||||
"name": "Head Office",
|
||||
"nameDecorated": "Head Office",
|
||||
"externalId": "1",
|
||||
"openingDate": [2009,1,1],
|
||||
"hierarchy": "."
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -1876,8 +1893,8 @@ Request Body:
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"officeId": 3,
|
||||
"resourceId": 3,
|
||||
"officeId": 1,
|
||||
"resourceId": 1,
|
||||
"changes": {
|
||||
"name": "Name is updated"
|
||||
}
|
||||
@@ -1994,9 +2011,9 @@ Request Body:
|
||||
},
|
||||
"annualInterestRate": 21,
|
||||
"amortizationType": {
|
||||
"id": 0,
|
||||
"code": "amortizationType.equal.principal",
|
||||
"value": "Equal principle payments"
|
||||
"id": 1,
|
||||
"code": "amortizationType.equal.installments",
|
||||
"value": "Equal installments"
|
||||
},
|
||||
"interestType": {
|
||||
"id": 0,
|
||||
@@ -2243,9 +2260,9 @@ Request Body:
|
||||
},
|
||||
"annualInterestRate": 21,
|
||||
"amortizationType": {
|
||||
"id": 0,
|
||||
"code": "amortizationType.equal.principal",
|
||||
"value": "Equal principle payments"
|
||||
"id": 1,
|
||||
"code": "amortizationType.equal.installments",
|
||||
"value": "Equal installments"
|
||||
},
|
||||
"interestType": {
|
||||
"id": 0,
|
||||
@@ -2354,14 +2371,39 @@ Request Body:
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/currencies</code>
|
||||
<code class="method-response">{
|
||||
"selectedCurrencyOptions" : [ {
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"displaySymbol": "$",
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
}]
|
||||
"selectedCurrencyOptions": [
|
||||
{
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"displaySymbol": "$",
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
}
|
||||
],
|
||||
"currencyOptions": [
|
||||
{
|
||||
"code": "AFN",
|
||||
"name": "Afghanistan Afghani",
|
||||
"decimalPlaces": 2,
|
||||
"nameCode": "currency.AFN",
|
||||
"displayLabel": "Afghanistan Afghani [AFN]"
|
||||
},
|
||||
{
|
||||
"code": "ALL",
|
||||
"name": "Albanian Lek",
|
||||
"decimalPlaces": 2,
|
||||
"nameCode": "currency.ALL",
|
||||
"displayLabel": "Albanian Lek [ALL]"
|
||||
},
|
||||
{
|
||||
"code": "ZWD",
|
||||
"name": "Zimbabwe Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"nameCode": "currency.ZWD",
|
||||
"displayLabel": "Zimbabwe Dollar [ZWD]"
|
||||
}
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -2474,7 +2516,7 @@ Request Body:
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2
|
||||
"resourceId": 4
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -2498,8 +2540,12 @@ Request Body:
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "MyNewCode",
|
||||
"systemDefined": false
|
||||
"name": "Gender",
|
||||
"systemDefined": true
|
||||
},{
|
||||
"id": 3,
|
||||
"name": "Education",
|
||||
"systemDefined": true
|
||||
}
|
||||
]
|
||||
</code>
|
||||
@@ -2532,8 +2578,8 @@ Request Body:
|
||||
<p>Updates the details of a code if it is not system defined.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">PUT https://Domain Name/api/v1/codes/2</code>
|
||||
<code class="method-request">PUT codes/2
|
||||
<code class="method-declaration">PUT https://Domain Name/api/v1/codes/4</code>
|
||||
<code class="method-request">PUT codes/4
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
@@ -2541,7 +2587,7 @@ Request Body:
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2,
|
||||
"resourceId": 4,
|
||||
"changes": {
|
||||
"name": "MyNewCode(changed)"
|
||||
}
|
||||
@@ -2557,12 +2603,12 @@ Request Body:
|
||||
<p>Deletes a code if it is not system defined.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">DELETE https://Domain Name/api/v1/codes/2</code>
|
||||
<code class="method-request">DELETE codes/2
|
||||
<code class="method-declaration">DELETE https://Domain Name/api/v1/codes/4</code>
|
||||
<code class="method-request">DELETE codes/4
|
||||
Content-Type: application/json
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2
|
||||
"resourceId": 4
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -2803,7 +2849,7 @@ Request Body:
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -2820,39 +2866,9 @@ Request Body:
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/charges</code>
|
||||
<code class="method-response">[
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Loan service fee",
|
||||
"active": false,
|
||||
"penalty": false,
|
||||
"currency": {
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"displaySymbol": "$",
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"amount": 230.56,
|
||||
"chargeTimeType": {
|
||||
"id": 1,
|
||||
"code": "chargeTimeType.disbursement",
|
||||
"value": "Disbursement"
|
||||
},
|
||||
"chargeAppliesTo": {
|
||||
"id": 1,
|
||||
"code": "chargeAppliesTo.loan",
|
||||
"value": "Loan"
|
||||
},
|
||||
"chargeCalculationType": {
|
||||
"id": 1,
|
||||
"code": "chargeCalculationType.flat",
|
||||
"value": "Flat"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "newcharge",
|
||||
"name": "Loan service fee",
|
||||
"active": true,
|
||||
"penalty": false,
|
||||
"currency": {
|
||||
@@ -2863,7 +2879,7 @@ Request Body:
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"amount": 456,
|
||||
"amount": 230.560000,
|
||||
"chargeTimeType": {
|
||||
"id": 1,
|
||||
"code": "chargeTimeType.disbursement",
|
||||
@@ -2891,14 +2907,14 @@ Request Body:
|
||||
<h4>Retrieve a Charge</h4>
|
||||
<p>Returns the details of a defined Charge.</p>
|
||||
<p>Example Requests: </p>
|
||||
<div class=apiClick>charges/2</div>
|
||||
<div class=apiClick>charges/1</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/charges/2</code>
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/charges/1</code>
|
||||
<code class="method-response">{
|
||||
"id": 2,
|
||||
"id": 1,
|
||||
"name": "Loan service fee",
|
||||
"active": false,
|
||||
"active": true,
|
||||
"penalty": false,
|
||||
"currency": {
|
||||
"code": "USD",
|
||||
@@ -2908,7 +2924,7 @@ Request Body:
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"amount": 230.56,
|
||||
"amount": 230.560000,
|
||||
"chargeTimeType": {
|
||||
"id": 1,
|
||||
"code": "chargeTimeType.disbursement",
|
||||
@@ -2945,7 +2961,7 @@ Request Body:
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2,
|
||||
"resourceId": 1,
|
||||
"changes": {
|
||||
"name": "Loan service fee(changed)"
|
||||
}
|
||||
@@ -2961,12 +2977,12 @@ Request Body:
|
||||
<p>Deletes a Charge.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">DELETE https://Domain Name/api/v1/charges/2</code>
|
||||
<code class="method-request">DELETE charges/2
|
||||
<code class="method-declaration">DELETE https://Domain Name/api/v1/charges/1</code>
|
||||
<code class="method-request">DELETE charges/1
|
||||
Content-Type: application/json
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -3540,7 +3556,7 @@ Request Body:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="authentication_permissions" name="authentication_permissions" class="old-syle-anchor"> </a>
|
||||
<a id="authenticate_request" name="authenticate_request" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Verify authentication</h4>
|
||||
@@ -3562,9 +3578,7 @@ No Request Body
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/authentication?username={username}&password={password}</code>
|
||||
|
||||
<code class="method-request">POST authentication?username=mifos&password=fail
|
||||
Content-Type: application/json
|
||||
No Request Body
|
||||
@@ -3578,7 +3592,7 @@ No Request Body
|
||||
"errors": []
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- start of users api docs -->
|
||||
@@ -4143,7 +4157,7 @@ Request body:
|
||||
<tr><td></td><td>datatables/{datatable}/{apptableId}/{datatableId}</td><td></td><td><a href="#datatables_update_1M">Update Entry in Data Table (One to Many)</a></td><td></td><td><a href="#datatables_delete_1M">Delete Entry in Data Table (One to Many)</a></td></tr>
|
||||
<tr class="alt"><td><a href="#reports">REPORT</a></td><td>reports</td><td></td><td><a href="#reports_list">List Reports</a></td><td></td><td></td></tr>
|
||||
<tr><td></td><td>reports/{reportName}</td><td></td><td><a href="#report_run">Run a Report</a></td><td></td><td></td></tr>
|
||||
<tr class="alt"><td><a href="#authentication">AUTHENTICATION</a></td><td>authentication</td><td><a href="#authentication_permissions">Verify Authentication</a></td><td></td><td></td><td></td></tr>
|
||||
<tr class="alt"><td><a href="#authentication">AUTHENTICATION</a></td><td>authentication</td><td><a href="#authenticate_request">Verify Authentication</a></td><td></td><td></td><td></td></tr>
|
||||
<tr><td><a href="#users">USER</a></td><td>users</td><td><a href="#users_create">Create a User</a></td><td><a href="#users_list">List Users</a></td><td></td><td></td></tr>
|
||||
<tr class="alt"><td></td><td>users/{userId}</td><td></td><td><a href="#users_retrieve">Retrieve a User</a></td><td><a href="#users_update">Update a User</a></td><td><a href="#users_delete">Delete a User</a></td></tr>
|
||||
<tr><td><a href="#roles">ROLE</a></td><td>roles</td><td><a href="#roles_create">Create a New Role</a></td><td><a href="#roles_list">List Roles</a></td><td></td><td></td></tr>
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
DROP TABLE IF EXISTS `additional client fields data`;
|
||||
DROP TABLE IF EXISTS `extra family details data`;
|
||||
DROP TABLE IF EXISTS `additional loan fields data`;
|
||||
|
||||
CREATE TABLE `additional client fields data` (
|
||||
`client_id` bigint(20) NOT NULL,
|
||||
`Business Description` varchar(100) DEFAULT NULL,
|
||||
`Years in Business` int(11) DEFAULT NULL,
|
||||
`Gender_cd` int(11) DEFAULT NULL,
|
||||
`Education_cv` varchar(60) DEFAULT NULL,
|
||||
`Next Visit` date DEFAULT NULL,
|
||||
`Highest Rate Paid` decimal(19,6) DEFAULT NULL,
|
||||
`Comment` text,
|
||||
PRIMARY KEY (`client_id`),
|
||||
CONSTRAINT `FK_Additional Client Fields Data_1` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `extra family details data` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`client_id` bigint(20) NOT NULL,
|
||||
`Name` varchar(40) DEFAULT NULL,
|
||||
`Date of Birth` date DEFAULT NULL,
|
||||
`Points Score` int(11) DEFAULT NULL,
|
||||
`Education_cdHighest` int(11) DEFAULT NULL,
|
||||
`Other Notes` text,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `FK_Extra Family Details Data_1` (`client_id`),
|
||||
CONSTRAINT `FK_Extra Family Details Data_1` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `additional loan fields data` (
|
||||
`loan_id` bigint(20) NOT NULL,
|
||||
`Business Description` varchar(100) DEFAULT NULL,
|
||||
`Years in Business` int(11) DEFAULT NULL,
|
||||
`Gender_cd` int(11) DEFAULT NULL,
|
||||
`Education_cv` varchar(60) DEFAULT NULL,
|
||||
`Next Visit` date DEFAULT NULL,
|
||||
`Highest Rate Paid` decimal(19,6) DEFAULT NULL,
|
||||
`Comment` text,
|
||||
PRIMARY KEY (`loan_id`),
|
||||
CONSTRAINT `FK_Additional Loan Fields Data_1` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
@@ -21,6 +21,7 @@ INSERT INTO `mifosplatform-tenants`.`tenants`
|
||||
(`name`, `identifier`,`schema_name`)
|
||||
VALUES
|
||||
('Default Demo Tenant', 'default' ,'mifostenant-default'),
|
||||
('API Docs Demo', 'apidocs' ,'mifostenant-apidocs'),
|
||||
('GK Maarg', 'gk-maarg' ,'mifostenant-gk-maarg'),
|
||||
('Latam Demo', 'latam' ,'mifostenant-latam'),
|
||||
('Bare bones Demo', 'barebones' ,'mifostenant-barebones');
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,15 @@
|
||||
default Demo
|
||||
======
|
||||
|
||||
This demo database contains:
|
||||
|
||||
- DDL of latest schema
|
||||
|
||||
- Minimum reference data required for deployment of platform which is:
|
||||
- Its mandatory to have one selected currency so we default to several of latin-america currencies
|
||||
- Its mandatory to have one root or head office, so we have one created by default called a 'Latam HO'
|
||||
- Permissions supported/needed by latest release of software are setup
|
||||
- Its mandatory to have at least one role when creating new users so we have one role created by default called 'Super user' which has the special permission 'Full Authorisation'. Any user with this role can do anything in the system.
|
||||
- Its required to have at least one application user setup so remaining setup can be done through ui so we have on application user created by default with username 'quipo' with a password of 'quipo'. Application users must be associated with an office and a role so this user is associated with 'Latam HO' and 'Super user' role allowing this user to do any operation in any office(branch).
|
||||
|
||||
Minimum amount of data to support api-docs interaction.
|
||||
+96
-290
File diff suppressed because one or more lines are too long
+52
@@ -0,0 +1,52 @@
|
||||
-- add code and code values for datatables dropdowns
|
||||
INSERT INTO `m_code` (`id`, `code_name`, `is_system_defined`) VALUES (2, 'Gender', 1);
|
||||
INSERT INTO `m_code` (`id`, `code_name`, `is_system_defined`) VALUES (3, 'Education', 1);
|
||||
|
||||
INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (2, 'Male', 1);
|
||||
INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (2, 'Female', 2);
|
||||
|
||||
INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'Primary', 1);
|
||||
INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'Secondary', 2);
|
||||
INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'University', 3);
|
||||
|
||||
DROP TABLE IF EXISTS `extra_client_details`;
|
||||
CREATE TABLE `extra_client_details` (
|
||||
`client_id` bigint(20) NOT NULL,
|
||||
`Business Description` varchar(100) DEFAULT NULL,
|
||||
`Years in Business` int(11) DEFAULT NULL,
|
||||
`Gender_cd` int(11) DEFAULT NULL,
|
||||
`Education_cv` varchar(60) DEFAULT NULL,
|
||||
`Next Visit` date DEFAULT NULL,
|
||||
`Highest Rate Paid` decimal(19,6) DEFAULT NULL,
|
||||
`Comment` text,
|
||||
PRIMARY KEY (`client_id`),
|
||||
CONSTRAINT `FK_latam_extra_client_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
DROP TABLE IF EXISTS `extra_family_details`;
|
||||
CREATE TABLE `extra_family_details` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`client_id` bigint(20) NOT NULL,
|
||||
`Name` varchar(40) DEFAULT NULL,
|
||||
`Date of Birth` date DEFAULT NULL,
|
||||
`Points Score` int(11) DEFAULT NULL,
|
||||
`Education_cd_Highest` int(11) DEFAULT NULL,
|
||||
`Other Notes` text,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `FK_Extra Family Details Data_1` (`client_id`),
|
||||
CONSTRAINT `FK_latam_family_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
DROP TABLE IF EXISTS `extra_loan_details`;
|
||||
CREATE TABLE `extra_loan_details` (
|
||||
`loan_id` bigint(20) NOT NULL,
|
||||
`Business Description` varchar(100) DEFAULT NULL,
|
||||
`Years in Business` int(11) DEFAULT NULL,
|
||||
`Gender_cd` int(11) DEFAULT NULL,
|
||||
`Education_cv` varchar(60) DEFAULT NULL,
|
||||
`Next Visit` date DEFAULT NULL,
|
||||
`Highest Rate Paid` decimal(19,6) DEFAULT NULL,
|
||||
`Comment` text,
|
||||
PRIMARY KEY (`loan_id`),
|
||||
CONSTRAINT `FK_latam_extra_loan_details` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
@@ -0,0 +1,49 @@
|
||||
DROP TABLE IF EXISTS `latam_extra_client_details`;
|
||||
CREATE TABLE `latam_extra_client_details` (
|
||||
`client_id` bigint(20) NOT NULL,
|
||||
`Business Description` varchar(100) DEFAULT NULL,
|
||||
`Years in Business` int(11) DEFAULT NULL,
|
||||
`Gender_cd` int(11) DEFAULT NULL,
|
||||
`Education_cv` varchar(60) DEFAULT NULL,
|
||||
`Next Visit` date DEFAULT NULL,
|
||||
`Highest Rate Paid` decimal(19,6) DEFAULT NULL,
|
||||
`Comment` text,
|
||||
PRIMARY KEY (`client_id`),
|
||||
CONSTRAINT `FK_latam_extra_client_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
DROP TABLE IF EXISTS `latam_family_details`;
|
||||
CREATE TABLE `latam_family_details` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`client_id` bigint(20) NOT NULL,
|
||||
`Name` varchar(40) DEFAULT NULL,
|
||||
`Date of Birth` date DEFAULT NULL,
|
||||
`Points Score` int(11) DEFAULT NULL,
|
||||
`Education_cd_Highest` int(11) DEFAULT NULL,
|
||||
`Other Notes` text,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `FK_Extra Family Details Data_1` (`client_id`),
|
||||
CONSTRAINT `FK_latam_family_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
DROP TABLE IF EXISTS `latam_extra_loan_details`;
|
||||
CREATE TABLE `latam_extra_loan_details` (
|
||||
`loan_id` bigint(20) NOT NULL,
|
||||
`Business Description` varchar(100) DEFAULT NULL,
|
||||
`Years in Business` int(11) DEFAULT NULL,
|
||||
`Gender_cd` int(11) DEFAULT NULL,
|
||||
`Education_cv` varchar(60) DEFAULT NULL,
|
||||
`Next Visit` date DEFAULT NULL,
|
||||
`Highest Rate Paid` decimal(19,6) DEFAULT NULL,
|
||||
`Comment` text,
|
||||
PRIMARY KEY (`loan_id`),
|
||||
CONSTRAINT `FK_latam_extra_loan_details` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
INSERT INTO `mifostenant-latam`.`m_code` (`code_name`, `is_system_defined`) VALUES ('Gender', 1);
|
||||
INSERT INTO `mifostenant-latam`.`m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (2, 'Male', 1); INSERT INTO `mifostenant-latam`.`m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (2, 'Female', 2);
|
||||
|
||||
|
||||
INSERT INTO `mifostenant-latam`.`m_code` (`code_name`, `is_system_defined`) VALUES ('Education', 1);
|
||||
INSERT INTO `mifostenant-latam`.`m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'Primary', 1); INSERT INTO `mifostenant-latam`.`m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'Secondary', 2); INSERT INTO `mifostenant-latam`.`m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'University', 3);
|
||||
+22
-4
@@ -9,8 +9,8 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Used to process the query parameters provided in a API request to see features of
|
||||
* the RESTful API are being asked for such as:
|
||||
* Used to process the query parameters provided in a API request to see
|
||||
* features of the RESTful API are being asked for such as:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>Pretty printing through pretty=true, defaults to false</li>
|
||||
@@ -21,6 +21,23 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class ApiRequestParameterHelper {
|
||||
|
||||
public ApiRequestJsonSerializationSettings process(final MultivaluedMap<String, String> queryParameters,
|
||||
final Set<String> mandatoryResponseParameters) {
|
||||
|
||||
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(queryParameters);
|
||||
if (!responseParameters.isEmpty()) {
|
||||
responseParameters.addAll(mandatoryResponseParameters);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
public ApiRequestJsonSerializationSettings process(final MultivaluedMap<String, String> queryParameters) {
|
||||
|
||||
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(queryParameters);
|
||||
@@ -29,7 +46,8 @@ public class ApiRequestParameterHelper {
|
||||
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, commandId, makerCheckerable, includeJson);
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -25,8 +25,9 @@ public class CreateDatatableEntryCommandHandler implements NewCommandSourceHandl
|
||||
|
||||
this.writePlatformService.newDatatableEntry(command.entityName(), command.getApptableId(), command);
|
||||
|
||||
// FIXME - kw - need to find office and either group/client/loan that
|
||||
// this datatable is against.
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(command.getApptableId()).build();
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(command.getApptableId()) //
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+635
-817
File diff suppressed because it is too large
Load Diff
+14
-4
@@ -76,10 +76,11 @@ public class LoansApiResource {
|
||||
"annualInterestRate", "repaymentFrequencyType", "interestRateFrequencyType", "amortizationType", "interestType",
|
||||
"interestCalculationPeriodType", "submittedOnDate", "approvedOnDate", "expectedDisbursementDate", "actualDisbursementDate",
|
||||
"expectedFirstRepaymentOnDate", "interestChargedFromDate", "closedOnDate", "expectedMaturityDate", "status",
|
||||
"lifeCycleStatusDate", "repaymentSchedule", "transactions", "permissions", "convenienceData", "charges", "productOptions",
|
||||
"lifeCycleStatusDate", "repaymentSchedule", "transactions", "permissions", "convenienceData", "charges", "guarantor", "productOptions",
|
||||
"amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions", "repaymentFrequencyTypeOptions",
|
||||
"interestRateFrequencyTypeOptions", "fundOptions", "repaymentStrategyOptions", "chargeOptions", "loanOfficerId",
|
||||
"loanOfficerName", "loanOfficerOptions", "chargeTemplate"));
|
||||
"loanOfficerName", "loanOfficerOptions", "chargeTemplate", "transactionProcessingStrategyId",
|
||||
"termFrequency", "termPeriodFrequencyType"));
|
||||
|
||||
private final String resourceNameForPermissions = "LOAN";
|
||||
|
||||
@@ -201,6 +202,7 @@ public class LoansApiResource {
|
||||
Collection<LoanChargeData> charges = null;
|
||||
Collection<GuarantorData> guarantors = null;
|
||||
|
||||
final Set<String> mandatoryResponseParameters = new HashSet<String>();
|
||||
boolean convenienceDataRequired = false;
|
||||
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
if (!associationParameters.isEmpty()) {
|
||||
@@ -211,6 +213,7 @@ public class LoansApiResource {
|
||||
}
|
||||
|
||||
if (associationParameters.contains("guarantor")) {
|
||||
mandatoryResponseParameters.add("guarantor");
|
||||
guarantors = this.guarantorReadPlatformService.retrieveGuarantorsForLoan(loanId);
|
||||
if (CollectionUtils.isEmpty(guarantors)) {
|
||||
guarantors = null; // set back to null so doesn't appear in JSON
|
||||
@@ -218,6 +221,7 @@ public class LoansApiResource {
|
||||
}
|
||||
|
||||
if (associationParameters.contains("transactions")) {
|
||||
mandatoryResponseParameters.add("transactions");
|
||||
final Collection<LoanTransactionData> currentLoanRepayments = this.loanReadPlatformService.retrieveLoanTransactions(loanId);
|
||||
if (!CollectionUtils.isEmpty(currentLoanRepayments)) {
|
||||
loanRepayments = currentLoanRepayments;
|
||||
@@ -226,6 +230,10 @@ public class LoansApiResource {
|
||||
|
||||
if (associationParameters.contains("repaymentSchedule") || associationParameters.contains("permissions")) {
|
||||
|
||||
if (associationParameters.contains("repaymentSchedule")) {
|
||||
mandatoryResponseParameters.add("repaymentSchedule");
|
||||
}
|
||||
|
||||
DisbursementData singleDisbursement = loanBasicDetails.toDisburementData();
|
||||
repaymentSchedule = this.loanReadPlatformService.retrieveRepaymentSchedule(loanId, loanBasicDetails.getCurrency(),
|
||||
singleDisbursement, loanBasicDetails.getTotalDisbursementCharges(), loanBasicDetails.getInArrearsTolerance());
|
||||
@@ -236,7 +244,8 @@ public class LoansApiResource {
|
||||
if (associationParameters.contains("permissions")) {
|
||||
|
||||
if (repaymentSchedule == null) { throw new IllegalStateException(); }
|
||||
|
||||
mandatoryResponseParameters.add("permissions");
|
||||
|
||||
// FIXME - KW - Waive feature was changed to waive interest at
|
||||
// anytime so this permission checking is probably not needed -
|
||||
// look into.
|
||||
@@ -259,6 +268,7 @@ public class LoansApiResource {
|
||||
}
|
||||
|
||||
if (associationParameters.contains("charges")) {
|
||||
mandatoryResponseParameters.add("charges");
|
||||
charges = this.loanChargeReadPlatformService.retrieveLoanCharges(loanId);
|
||||
if (CollectionUtils.isEmpty(charges)) {
|
||||
charges = null; // set back to null so doesnt appear in JSON
|
||||
@@ -302,7 +312,7 @@ public class LoansApiResource {
|
||||
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
|
||||
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, null, guarantors);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters(), mandatoryResponseParameters);
|
||||
return this.toApiJsonSerializer.serialize(settings, loanAccount, LOAN_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
|
||||
+98
-100
@@ -4,113 +4,111 @@ import java.util.List;
|
||||
|
||||
public class DefaultLoanLifecycleStateMachine implements LoanLifecycleStateMachine {
|
||||
|
||||
private final List<LoanStatus> allowedLoanStatuses;
|
||||
private final List<LoanStatus> allowedLoanStatuses;
|
||||
|
||||
public DefaultLoanLifecycleStateMachine(List<LoanStatus> allowedLoanStatuses) {
|
||||
this.allowedLoanStatuses = allowedLoanStatuses;
|
||||
}
|
||||
public DefaultLoanLifecycleStateMachine(List<LoanStatus> allowedLoanStatuses) {
|
||||
this.allowedLoanStatuses = allowedLoanStatuses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanStatus transition(LoanEvent loanEvent, LoanStatus from) {
|
||||
@Override
|
||||
public LoanStatus transition(LoanEvent loanEvent, LoanStatus from) {
|
||||
|
||||
LoanStatus newState = null;
|
||||
LoanStatus newState = from;
|
||||
|
||||
switch (loanEvent) {
|
||||
case LOAN_CREATED:
|
||||
if (from == null) {
|
||||
newState = stateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL,
|
||||
allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_REJECTED:
|
||||
if (from.hasStateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL)) {
|
||||
newState = stateOf(LoanStatus.REJECTED, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_APPROVED:
|
||||
if (from.hasStateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL)) {
|
||||
newState = stateOf(LoanStatus.APPROVED, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_WITHDRAWN:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.SUBMITED_AND_PENDING_APPROVAL, LoanStatus.APPROVED)) {
|
||||
newState = stateOf(LoanStatus.WITHDRAWN_BY_CLIENT, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_DISBURSED:
|
||||
if (from.hasStateOf(LoanStatus.APPROVED)) {
|
||||
newState = stateOf(LoanStatus.ACTIVE, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_APPROVAL_UNDO:
|
||||
if (from.hasStateOf(LoanStatus.APPROVED)) {
|
||||
newState = stateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_DISBURSAL_UNDO:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE)) {
|
||||
newState = stateOf(LoanStatus.APPROVED, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_REPAYMENT_OR_WAIVER:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE, LoanStatus.CLOSED_OBLIGATIONS_MET, LoanStatus.OVERPAID)) {
|
||||
newState = stateOf(LoanStatus.ACTIVE, allowedLoanStatuses);
|
||||
} else {
|
||||
newState = from;
|
||||
}
|
||||
break;
|
||||
case REPAID_IN_FULL:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE, LoanStatus.OVERPAID)) {
|
||||
newState = stateOf(LoanStatus.CLOSED_OBLIGATIONS_MET, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case WRITE_OFF_OUTSTANDING:
|
||||
if (this.anyOfAllowedWhenComingFrom(from,LoanStatus.ACTIVE)) {
|
||||
newState = stateOf(LoanStatus.CLOSED_WRITTEN_OFF, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_RESCHEDULE:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE)) {
|
||||
newState = stateOf(LoanStatus.CLOSED_RESCHEDULE_OUTSTANDING_AMOUNT, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case INTERST_REBATE_OWED:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.CLOSED_OBLIGATIONS_MET)) {
|
||||
newState = stateOf(LoanStatus.CLOSED_OBLIGATIONS_MET, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_OVERPAYMENT:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.CLOSED_OBLIGATIONS_MET, LoanStatus.ACTIVE)) {
|
||||
newState = stateOf(LoanStatus.OVERPAID, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (loanEvent) {
|
||||
case LOAN_CREATED:
|
||||
if (from == null) {
|
||||
newState = stateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_REJECTED:
|
||||
if (from.hasStateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL)) {
|
||||
newState = stateOf(LoanStatus.REJECTED, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_APPROVED:
|
||||
if (from.hasStateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL)) {
|
||||
newState = stateOf(LoanStatus.APPROVED, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_WITHDRAWN:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.SUBMITED_AND_PENDING_APPROVAL, LoanStatus.APPROVED)) {
|
||||
newState = stateOf(LoanStatus.WITHDRAWN_BY_CLIENT, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_DISBURSED:
|
||||
if (from.hasStateOf(LoanStatus.APPROVED)) {
|
||||
newState = stateOf(LoanStatus.ACTIVE, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_APPROVAL_UNDO:
|
||||
if (from.hasStateOf(LoanStatus.APPROVED)) {
|
||||
newState = stateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_DISBURSAL_UNDO:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE)) {
|
||||
newState = stateOf(LoanStatus.APPROVED, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_REPAYMENT_OR_WAIVER:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE, LoanStatus.CLOSED_OBLIGATIONS_MET, LoanStatus.OVERPAID)) {
|
||||
newState = stateOf(LoanStatus.ACTIVE, allowedLoanStatuses);
|
||||
} else {
|
||||
newState = from;
|
||||
}
|
||||
break;
|
||||
case REPAID_IN_FULL:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE, LoanStatus.OVERPAID)) {
|
||||
newState = stateOf(LoanStatus.CLOSED_OBLIGATIONS_MET, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case WRITE_OFF_OUTSTANDING:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE)) {
|
||||
newState = stateOf(LoanStatus.CLOSED_WRITTEN_OFF, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_RESCHEDULE:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE)) {
|
||||
newState = stateOf(LoanStatus.CLOSED_RESCHEDULE_OUTSTANDING_AMOUNT, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case INTERST_REBATE_OWED:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.CLOSED_OBLIGATIONS_MET)) {
|
||||
newState = stateOf(LoanStatus.CLOSED_OBLIGATIONS_MET, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_OVERPAYMENT:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.CLOSED_OBLIGATIONS_MET, LoanStatus.ACTIVE)) {
|
||||
newState = stateOf(LoanStatus.OVERPAID, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return newState;
|
||||
}
|
||||
return newState;
|
||||
}
|
||||
|
||||
private LoanStatus stateOf(LoanStatus state, List<LoanStatus> allowedLoanStatuses) {
|
||||
LoanStatus match = null;
|
||||
for (LoanStatus loanStatus : allowedLoanStatuses) {
|
||||
if (loanStatus.hasStateOf(state)) {
|
||||
match = loanStatus;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
private LoanStatus stateOf(LoanStatus state, List<LoanStatus> allowedLoanStatuses) {
|
||||
LoanStatus match = null;
|
||||
for (LoanStatus loanStatus : allowedLoanStatuses) {
|
||||
if (loanStatus.hasStateOf(state)) {
|
||||
match = loanStatus;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
private boolean anyOfAllowedWhenComingFrom(final LoanStatus state,
|
||||
final LoanStatus... allowedStates) {
|
||||
boolean allowed = false;
|
||||
private boolean anyOfAllowedWhenComingFrom(final LoanStatus state, final LoanStatus... allowedStates) {
|
||||
boolean allowed = false;
|
||||
|
||||
for (LoanStatus allowedState : allowedStates) {
|
||||
if (state.hasStateOf(allowedState)) {
|
||||
allowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (LoanStatus allowedState : allowedStates) {
|
||||
if (state.hasStateOf(allowedState)) {
|
||||
allowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return allowed;
|
||||
}
|
||||
return allowed;
|
||||
}
|
||||
}
|
||||
+101
-100
@@ -803,32 +803,32 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
|
||||
LocalDate rejectedOn = command.localDateValueOfParameterNamed("rejectedOnDate");
|
||||
if (rejectedOn == null) {
|
||||
rejectedOn = command.localDateValueOfParameterNamed("eventDate");
|
||||
}
|
||||
|
||||
LocalDate rejectedOn = command.localDateValueOfParameterNamed("rejectedOnDate");
|
||||
if (rejectedOn == null) {
|
||||
rejectedOn = command.localDateValueOfParameterNamed("eventDate");
|
||||
}
|
||||
final Locale locale = new Locale(command.locale());
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
|
||||
final Locale locale = new Locale(command.locale());
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
this.rejectedOnDate = rejectedOn.toDate();
|
||||
this.closedOnDate = rejectedOn.toDate();
|
||||
actualChanges.put("locale", command.locale());
|
||||
actualChanges.put("dateFormat", command.dateFormat());
|
||||
actualChanges.put("rejectedOnDate", rejectedOn.toString(fmt));
|
||||
actualChanges.put("closedOnDate", rejectedOn.toString(fmt));
|
||||
|
||||
this.rejectedOnDate = rejectedOn.toDate();
|
||||
this.closedOnDate = rejectedOn.toDate();
|
||||
actualChanges.put("locale", command.locale());
|
||||
actualChanges.put("dateFormat", command.dateFormat());
|
||||
actualChanges.put("rejectedOnDate", rejectedOn.toString(fmt));
|
||||
actualChanges.put("closedOnDate", rejectedOn.toString(fmt));
|
||||
|
||||
if (rejectedOn.isBefore(getSubmittedOnDate())) {
|
||||
final String errorMessage = "The date on which a loan is rejected cannot be before its submittal date: "
|
||||
+ getSubmittedOnDate().toString();
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, rejectedOn,
|
||||
getSubmittedOnDate());
|
||||
}
|
||||
if (rejectedOn.isAfter(new LocalDate())) {
|
||||
final String errorMessage = "The date on which a loan is rejected cannot be in the future.";
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, rejectedOn);
|
||||
if (rejectedOn.isBefore(getSubmittedOnDate())) {
|
||||
final String errorMessage = "The date on which a loan is rejected cannot be before its submittal date: "
|
||||
+ getSubmittedOnDate().toString();
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, rejectedOn,
|
||||
getSubmittedOnDate());
|
||||
}
|
||||
if (rejectedOn.isAfter(new LocalDate())) {
|
||||
final String errorMessage = "The date on which a loan is rejected cannot be in the future.";
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, rejectedOn);
|
||||
}
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
@@ -843,33 +843,33 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
|
||||
LocalDate withdrawnOn = command.localDateValueOfParameterNamed("withdrawnOnDate");
|
||||
if (withdrawnOn == null) {
|
||||
withdrawnOn = command.localDateValueOfParameterNamed("eventDate");
|
||||
}
|
||||
|
||||
LocalDate withdrawnOn = command.localDateValueOfParameterNamed("withdrawnOnDate");
|
||||
if (withdrawnOn == null) {
|
||||
withdrawnOn = command.localDateValueOfParameterNamed("eventDate");
|
||||
}
|
||||
final Locale locale = new Locale(command.locale());
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
|
||||
final Locale locale = new Locale(command.locale());
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
this.withdrawnOnDate = withdrawnOn.toDate();
|
||||
this.closedOnDate = withdrawnOn.toDate();
|
||||
actualChanges.put("locale", command.locale());
|
||||
actualChanges.put("dateFormat", command.dateFormat());
|
||||
actualChanges.put("withdrawnOnDate", withdrawnOn.toString(fmt));
|
||||
actualChanges.put("closedOnDate", withdrawnOn.toString(fmt));
|
||||
|
||||
this.withdrawnOnDate = withdrawnOn.toDate();
|
||||
this.closedOnDate = withdrawnOn.toDate();
|
||||
actualChanges.put("locale", command.locale());
|
||||
actualChanges.put("dateFormat", command.dateFormat());
|
||||
actualChanges.put("withdrawnOnDate", withdrawnOn.toString(fmt));
|
||||
actualChanges.put("closedOnDate", withdrawnOn.toString(fmt));
|
||||
if (withdrawnOn.isBefore(getSubmittedOnDate())) {
|
||||
final String errorMessage = "The date on which a loan is withdrawn cannot be before its submittal date: "
|
||||
+ getSubmittedOnDate().toString();
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, command,
|
||||
getSubmittedOnDate());
|
||||
}
|
||||
|
||||
if (withdrawnOn.isBefore(getSubmittedOnDate())) {
|
||||
final String errorMessage = "The date on which a loan is withdrawn cannot be before its submittal date: "
|
||||
+ getSubmittedOnDate().toString();
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, command,
|
||||
getSubmittedOnDate());
|
||||
}
|
||||
|
||||
if (withdrawnOn.isAfter(new LocalDate())) {
|
||||
final String errorMessage = "The date on which a loan is withdrawn cannot be in the future.";
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, command);
|
||||
if (withdrawnOn.isAfter(new LocalDate())) {
|
||||
final String errorMessage = "The date on which a loan is withdrawn cannot be in the future.";
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, command);
|
||||
}
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
@@ -883,34 +883,37 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
|
||||
// only do below if status has changed in the 'approval' case
|
||||
LocalDate approvedOn = command.localDateValueOfParameterNamed("approvedOnDate");
|
||||
String approvedOnDateChange = command.stringValueOfParameterNamed("approvedOnDate");
|
||||
if (approvedOn == null) {
|
||||
approvedOn = command.localDateValueOfParameterNamed("eventDate");
|
||||
approvedOnDateChange = command.stringValueOfParameterNamed("eventDate");
|
||||
}
|
||||
|
||||
LocalDate approvedOn = command.localDateValueOfParameterNamed("approvedOnDate");
|
||||
if (approvedOn == null) {
|
||||
approvedOn = command.localDateValueOfParameterNamed("eventDate");
|
||||
}
|
||||
this.approvedOnDate = approvedOn.toDate();
|
||||
actualChanges.put("locale", command.locale());
|
||||
actualChanges.put("dateFormat", command.dateFormat());
|
||||
actualChanges.put("approvedOnDate", approvedOnDateChange);
|
||||
|
||||
this.approvedOnDate = approvedOn.toDate();
|
||||
actualChanges.put("locale", command.locale());
|
||||
actualChanges.put("dateFormat", command.dateFormat());
|
||||
actualChanges.put("approvedOnDate", command.stringValueOfParameterNamed("approvedOnDate"));
|
||||
final LocalDate submittalDate = new LocalDate(this.submittedOnDate);
|
||||
if (approvedOn.isBefore(submittalDate)) {
|
||||
final String errorMessage = "The date on which a loan is approved cannot be before its submittal date: "
|
||||
+ submittalDate.toString();
|
||||
throw new InvalidLoanStateTransitionException("approval", "cannot.be.before.submittal.date", errorMessage, getApprovedOnDate(),
|
||||
submittalDate);
|
||||
}
|
||||
if (approvedOn.isAfter(new LocalDate())) {
|
||||
final String errorMessage = "The date on which a loan is approved cannot be in the future.";
|
||||
throw new InvalidLoanStateTransitionException("approval", "cannot.be.a.future.date", errorMessage, getApprovedOnDate());
|
||||
}
|
||||
|
||||
final LocalDate submittalDate = new LocalDate(this.submittedOnDate);
|
||||
if (approvedOn.isBefore(submittalDate)) {
|
||||
final String errorMessage = "The date on which a loan is approved cannot be before its submittal date: "
|
||||
+ submittalDate.toString();
|
||||
throw new InvalidLoanStateTransitionException("approval", "cannot.be.before.submittal.date", errorMessage, getApprovedOnDate(),
|
||||
submittalDate);
|
||||
}
|
||||
if (approvedOn.isAfter(new LocalDate())) {
|
||||
final String errorMessage = "The date on which a loan is approved cannot be in the future.";
|
||||
throw new InvalidLoanStateTransitionException("approval", "cannot.be.a.future.date", errorMessage, getApprovedOnDate());
|
||||
}
|
||||
|
||||
if (this.loanofficer != null) {
|
||||
final LoanOfficerAssignmentHistory loanOfficerAssignmentHistory = LoanOfficerAssignmentHistory.createNew(this,
|
||||
this.loanofficer, approvedOn);
|
||||
this.loanOfficerHistory.add(loanOfficerAssignmentHistory);
|
||||
if (this.loanofficer != null) {
|
||||
final LoanOfficerAssignmentHistory loanOfficerAssignmentHistory = LoanOfficerAssignmentHistory.createNew(this,
|
||||
this.loanofficer, approvedOn);
|
||||
this.loanOfficerHistory.add(loanOfficerAssignmentHistory);
|
||||
}
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
@@ -925,13 +928,13 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (!statusEnum.hasStateOf(currentStatus)) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
|
||||
this.approvedOnDate = null;
|
||||
actualChanges.put("approvedOnDate", "");
|
||||
|
||||
this.loanOfficerHistory.clear();
|
||||
}
|
||||
|
||||
this.approvedOnDate = null;
|
||||
actualChanges.put("approvedOnDate", "");
|
||||
|
||||
this.loanOfficerHistory.clear();
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
@@ -952,28 +955,28 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
|
||||
LocalDate disbursedOn = command.localDateValueOfParameterNamed("disbursedOnDate");
|
||||
if (disbursedOn == null) {
|
||||
disbursedOn = command.localDateValueOfParameterNamed("eventDate");
|
||||
}
|
||||
|
||||
LocalDate disbursedOn = command.localDateValueOfParameterNamed("disbursedOnDate");
|
||||
if (disbursedOn == null) {
|
||||
disbursedOn = command.localDateValueOfParameterNamed("eventDate");
|
||||
}
|
||||
final Locale locale = new Locale(command.locale());
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
|
||||
final Locale locale = new Locale(command.locale());
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
this.disbursedOnDate = disbursedOn.toDate();
|
||||
this.expectedMaturityDate = determineExpectedMaturityDate().toDate();
|
||||
|
||||
this.disbursedOnDate = disbursedOn.toDate();
|
||||
this.expectedMaturityDate = determineExpectedMaturityDate().toDate();
|
||||
actualChanges.put("locale", command.locale());
|
||||
actualChanges.put("dateFormat", command.dateFormat());
|
||||
actualChanges.put("disbursedOnDate", disbursedOn.toString(fmt));
|
||||
actualChanges.put("expectedMaturityDate", LocalDate.fromDateFields(this.expectedDisbursedOnDate).toString(fmt));
|
||||
|
||||
actualChanges.put("locale", command.locale());
|
||||
actualChanges.put("dateFormat", command.dateFormat());
|
||||
actualChanges.put("disbursedOnDate", disbursedOn.toString(fmt));
|
||||
actualChanges.put("expectedMaturityDate", LocalDate.fromDateFields(this.expectedDisbursedOnDate).toString(fmt));
|
||||
handleDisbursementTransaction(disbursedOn);
|
||||
|
||||
handleDisbursementTransaction(disbursedOn);
|
||||
|
||||
if (isRepaymentScheduleRegenerationRequiredForDisbursement(disbursedOn)) {
|
||||
regenerateRepaymentSchedule(currency);
|
||||
if (isRepaymentScheduleRegenerationRequiredForDisbursement(disbursedOn)) {
|
||||
regenerateRepaymentSchedule(currency);
|
||||
}
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
@@ -1067,19 +1070,17 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (!statusEnum.hasStateOf(currentStatus)) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
|
||||
this.approvedOnDate = null;
|
||||
actualChanges.put("disbursedOnDate", "");
|
||||
|
||||
updateLoanToPreDisbursalState();
|
||||
}
|
||||
|
||||
this.approvedOnDate = null;
|
||||
actualChanges.put("disbursedOnDate", "");
|
||||
|
||||
updateLoanToPreDisbursalState();
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
private void updateLoanToPreDisbursalState() {
|
||||
this.loanStatus = LoanStatus.APPROVED.getValue();
|
||||
|
||||
this.loanTransactions.clear();
|
||||
this.disbursedOnDate = null;
|
||||
|
||||
|
||||
+1
-2
@@ -2,6 +2,5 @@ package org.mifosplatform.portfolio.loanaccount.domain;
|
||||
|
||||
public interface LoanLifecycleStateMachine {
|
||||
|
||||
LoanStatus transition(LoanEvent loanEvent, LoanStatus from);
|
||||
|
||||
LoanStatus transition(LoanEvent loanEvent, LoanStatus from);
|
||||
}
|
||||
|
||||
+33
-25
@@ -294,13 +294,15 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
"User has no authority to approve loan with a date in the past."); }
|
||||
|
||||
final Map<String, Object> changes = loan.loanApplicationApproval(command, defaultLoanLifecycleStateMachine());
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
changes.put("note", noteText);
|
||||
this.noteRepository.save(note);
|
||||
if (!changes.isEmpty()) {
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
changes.put("note", noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
@@ -323,12 +325,14 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
final Map<String, Object> changes = loan.undoApproval(defaultLoanLifecycleStateMachine());
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
if (!changes.isEmpty()) {
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
@@ -359,12 +363,14 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
"User has no authority to reject loan with a date in the past."); }
|
||||
|
||||
final Map<String, Object> changes = loan.loanApplicationRejection(command, defaultLoanLifecycleStateMachine());
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
if (!changes.isEmpty()) {
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
@@ -395,12 +401,14 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
"User has no authority to mark loan as withdrawn by applicant with a date in the past."); }
|
||||
|
||||
final Map<String, Object> changes = loan.loanApplicationWithdrawnByApplicant(command, defaultLoanLifecycleStateMachine());
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
if (!changes.isEmpty()) {
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
|
||||
+37
-33
@@ -121,35 +121,37 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final ApplicationCurrency currency = this.applicationCurrencyRepository.findOneByCode(loan.getPrincpal().getCurrencyCode());
|
||||
|
||||
final Map<String, Object> changes = loan.disburse(command, defaultLoanLifecycleStateMachine(), currency);
|
||||
// variable stores Id's of all existing loan transactions (newly created
|
||||
// loan transactions would not have an Id before save)
|
||||
Set<Long> existingLoanTransactionIds = new HashSet<Long>();
|
||||
for(LoanTransaction loanTransaction:loan.getLoanTransactions()){
|
||||
if(!(loanTransaction.getId()==null)){
|
||||
existingLoanTransactionIds.add(loanTransaction.getId());
|
||||
}
|
||||
}
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
// make a call to accounting
|
||||
if (loan.isAccountingEnabledOnLoanProduct()) {
|
||||
/***
|
||||
* Variable holds list of all newly created loan transactions during
|
||||
* this disbursal
|
||||
**/
|
||||
List<LoanTransaction> newLoanTransactions = new ArrayList<LoanTransaction>();
|
||||
for (LoanTransaction loanTransaction : loan.getLoanTransactions()) {
|
||||
if (!existingLoanTransactionIds.contains(loanTransaction.getId())) {
|
||||
newLoanTransactions.add(loanTransaction);
|
||||
if (!changes.isEmpty()) {
|
||||
// variable stores Id's of all existing loan transactions (newly created
|
||||
// loan transactions would not have an Id before save)
|
||||
final Set<Long> existingLoanTransactionIds = new HashSet<Long>();
|
||||
for(LoanTransaction loanTransaction:loan.getLoanTransactions()){
|
||||
if(!(loanTransaction.getId()==null)){
|
||||
existingLoanTransactionIds.add(loanTransaction.getId());
|
||||
}
|
||||
}
|
||||
LoanDTO loanDTO = populateLoanDTO(loan, newLoanTransactions);
|
||||
journalEntryWritePlatformService.createJournalEntriesForLoan(loanDTO);
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
// make a call to accounting
|
||||
if (loan.isAccountingEnabledOnLoanProduct()) {
|
||||
/***
|
||||
* Variable holds list of all newly created loan transactions during
|
||||
* this disbursal
|
||||
**/
|
||||
List<LoanTransaction> newLoanTransactions = new ArrayList<LoanTransaction>();
|
||||
for (LoanTransaction loanTransaction : loan.getLoanTransactions()) {
|
||||
if (!existingLoanTransactionIds.contains(loanTransaction.getId())) {
|
||||
newLoanTransactions.add(loanTransaction);
|
||||
}
|
||||
}
|
||||
LoanDTO loanDTO = populateLoanDTO(loan, newLoanTransactions);
|
||||
journalEntryWritePlatformService.createJournalEntriesForLoan(loanDTO);
|
||||
}
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
@@ -172,12 +174,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
final Map<String, Object> changes = loan.undoDisbursal(defaultLoanLifecycleStateMachine());
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
if (!changes.isEmpty()) {
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
final InterestMethod interestMethod = InterestMethod.fromInt(command.integerValueOfParameterNamed("interestType"));
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command
|
||||
.integerValueOfParameterNamed("interestCalculationPeriodType"));
|
||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.integerValueOfParameterNamed("interestType"));
|
||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.integerValueOfParameterNamed("amortizationType"));
|
||||
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command
|
||||
.integerValueOfParameterNamed("repaymentFrequencyType"));
|
||||
final PeriodFrequencyType interestFrequencyType = PeriodFrequencyType.fromInt(command
|
||||
|
||||
Reference in New Issue
Block a user