update api-docs and loan functionality from api.
This commit is contained in:
+190
-176
@@ -327,7 +327,7 @@ function getBaseURL(docURL)
|
|||||||
<div class="tocMatrix">
|
<div class="tocMatrix">
|
||||||
<table class=matrixHeading>
|
<table class=matrixHeading>
|
||||||
<tr class="matrixHeadingBG"><td colspan=2 valign="top"><div class="matrixHeadingVerbs"><table><tr><td>RESOURCES</td></tr></table></div></td><td><table><tr><td><div class="matrixHeadingVerbs">POST</div></td></tr><tr><td><div class=matrixHeadingCommands>create/complex update</div></td></tr></table></td><td><table><tr><td><div class="matrixHeadingVerbs">GET</div></td></tr><tr><td><div class=matrixHeadingCommands>read</div></td></tr></table></td><td><table><tr><td><div class="matrixHeadingVerbs">PUT</div></td></tr><tr><td><div class=matrixHeadingCommands>update</div></td></tr></table></td><td><table><tr><td><div class="matrixHeadingVerbs">DELETE</div></td></tr><tr><td><div class=matrixHeadingCommands>delete</div></td></tr></table></td></tr>
|
<tr class="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 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><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>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- start of clients api docs -->
|
<!-- start of clients api docs -->
|
||||||
<a id="clients" name="clients" class="old-syle-anchor"> </a>
|
<a id="clients" name="clients" class="old-syle-anchor"> </a>
|
||||||
<div class="method-section">
|
<div class="method-section">
|
||||||
@@ -673,26 +670,37 @@ var jqxhr = $.ajax({
|
|||||||
</div>
|
</div>
|
||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
<code class="method-declaration">GET https://Domain Name/api/v1/clients</code>
|
<code class="method-declaration">GET https://Domain Name/api/v1/clients</code>
|
||||||
<code class="method-response">[ {
|
<code class="method-response">[
|
||||||
"id" : 14,
|
{
|
||||||
"accountNo": "14",
|
"id": 2,
|
||||||
"firstname" : "Patrick",
|
"accountNo": "000000002",
|
||||||
"middlename" : "J"
|
"externalId": "one/78",
|
||||||
"lastname" : "Asare-Frimpong",
|
"fullname": "New Business to Create",
|
||||||
"displayName" : "Patrick J Asare-Frimpong",
|
"displayName": "New Business to Create",
|
||||||
"officeId" : 2,
|
"officeId": 1,
|
||||||
"officeName" : "sub branch 1",
|
"officeName": "Head Office",
|
||||||
"externalId" : "123AB",
|
"joinedDate": [
|
||||||
"joinedDate" : [ 2012, 4, 18 ]
|
2006,
|
||||||
}, {
|
6,
|
||||||
"id" : 13,
|
13
|
||||||
"accountNo": "0000000AB5",
|
]
|
||||||
"fullname" : "My micro business Ltd."
|
},
|
||||||
"displayName" : "My micro business Ltd.",
|
{
|
||||||
"officeId" : 5,
|
"id": 1,
|
||||||
"officeName" : "Majmoua",
|
"accountNo": "000000001",
|
||||||
"joinedDate" : [ 2011, 12, 1 ]
|
"externalId": "786YYH7",
|
||||||
}... ]
|
"firstname": "Petra",
|
||||||
|
"lastname": "Yton",
|
||||||
|
"displayName": "Petra Yton",
|
||||||
|
"officeId": 1,
|
||||||
|
"officeName": "Head Office",
|
||||||
|
"joinedDate": [
|
||||||
|
2009,
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -713,23 +721,15 @@ var jqxhr = $.ajax({
|
|||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
<code class="method-declaration">GET https://Domain Name/api/v1/clients/template</code>
|
<code class="method-declaration">GET https://Domain Name/api/v1/clients/template</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"joinedDate" : [ 2012, 5, 29 ],
|
"officeId": 1,
|
||||||
"allowedOffices" : [ {
|
"joinedDate": [ 2013, 2, 5],
|
||||||
"id" : 1,
|
"allowedOffices": [
|
||||||
"name" : "Demo MFI Head Office"
|
{
|
||||||
}, {
|
"id": 1,
|
||||||
"id" : 2,
|
"name": "Head Office",
|
||||||
"name" : "sub branch 1"
|
"nameDecorated": "Head Office"
|
||||||
}, {
|
}
|
||||||
"id" : 8,
|
]
|
||||||
"name" : "moi aussi"
|
|
||||||
}, {
|
|
||||||
"id" : 3,
|
|
||||||
"name" : "sub branch 2"
|
|
||||||
}, {
|
|
||||||
"id" : 4,
|
|
||||||
"name" : "sub branch 3"
|
|
||||||
} ]
|
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -750,13 +750,19 @@ var jqxhr = $.ajax({
|
|||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
<code class="method-declaration">GET https://Domain Name/api/v1/clients/{clientId}</code>
|
<code class="method-declaration">GET https://Domain Name/api/v1/clients/{clientId}</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"id" : 1,
|
"id": 1,
|
||||||
"firstname" : "Patrick",
|
"accountNo": "000000001",
|
||||||
"lastname" : "O'Meara",
|
"externalId": "786YYH7",
|
||||||
"displayName" : "Patrick O'Meara",
|
"firstname": "Petra",
|
||||||
"officeId" : 1,
|
"lastname": "Yton",
|
||||||
"officeName" : "Demo MFI Head Office",
|
"displayName": "Petra Yton",
|
||||||
"joinedDate" : [ 2009, 1, 4 ]
|
"officeId": 1,
|
||||||
|
"officeName": "Head Office",
|
||||||
|
"joinedDate": [
|
||||||
|
2009,
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
]
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -792,8 +798,8 @@ Request Body:
|
|||||||
</code>
|
</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"officeId": 1,
|
"officeId": 1,
|
||||||
"clientId": 83,
|
"clientId": 1,
|
||||||
"resourceId": 83
|
"resourceId": 1
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -812,8 +818,8 @@ Request Body:
|
|||||||
</code>
|
</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"officeId": 1,
|
"officeId": 1,
|
||||||
"clientId": 84,
|
"clientId": 2,
|
||||||
"resourceId": 84
|
"resourceId": 2
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -826,7 +832,7 @@ Request Body:
|
|||||||
</div>
|
</div>
|
||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
<code class="method-declaration">PUT https://Domain Name/api/v1/clients/{clientId}</code>
|
<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
|
Content-Type: application/json
|
||||||
Request Body:
|
Request Body:
|
||||||
{
|
{
|
||||||
@@ -838,8 +844,8 @@ Request Body:
|
|||||||
</code>
|
</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"officeId": 1,
|
"officeId": 1,
|
||||||
"clientId": 83,
|
"clientId": 1,
|
||||||
"resourceId": 83,
|
"resourceId": 1,
|
||||||
"changes": {
|
"changes": {
|
||||||
"externalId": "786444UUUYYH7",
|
"externalId": "786444UUUYYH7",
|
||||||
"joinedDate": "09 June 2006",
|
"joinedDate": "09 June 2006",
|
||||||
@@ -1389,30 +1395,29 @@ Request Body:
|
|||||||
<br><br>
|
<br><br>
|
||||||
<div class=apiClick>loans/1?associations=all</div>
|
<div class=apiClick>loans/1?associations=all</div>
|
||||||
<br><br>
|
<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>
|
||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
<code class="method-declaration">GET https://Domain Name/api/v1/loans/{loanId}</code>
|
<code class="method-declaration">GET https://Domain Name/api/v1/loans/{loanId}</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
{
|
|
||||||
"id": 1,
|
"id": 1,
|
||||||
|
"accountNo": "000000001",
|
||||||
"clientId": 1,
|
"clientId": 1,
|
||||||
"clientName": "Willie O'Meara",
|
"clientName": "Petra Yton",
|
||||||
"loanProductId": 1,
|
"loanProductId": 1,
|
||||||
"loanProductName": "Agricultural Loan",
|
"loanProductName": "A new loan product for me",
|
||||||
"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)",
|
|
||||||
"status": {
|
"status": {
|
||||||
"id": 100,
|
"id": 100,
|
||||||
"code": "loanStatusType.submitted.and.pending.approval",
|
"code": "loanStatusType.submitted.and.pending.approval",
|
||||||
"value": "Submitted and pending approval"
|
"value": "Submitted and pending approval"
|
||||||
},
|
},
|
||||||
"currency": {
|
"currency": {
|
||||||
"code": "XOF",
|
"code": "USD",
|
||||||
"name": "CFA Franc BCEAO",
|
"name": "US Dollar",
|
||||||
"decimalPlaces": 0,
|
"decimalPlaces": 2,
|
||||||
"displaySymbol": "CFA",
|
"displaySymbol": "$",
|
||||||
"nameCode": "currency.XOF",
|
"nameCode": "currency.USD",
|
||||||
"displayLabel": "CFA Franc BCEAO (CFA)"
|
"displayLabel": "US Dollar ($)"
|
||||||
},
|
},
|
||||||
"principal": 100000,
|
"principal": 100000,
|
||||||
"termFrequency": 12,
|
"termFrequency": 12,
|
||||||
@@ -1509,7 +1514,10 @@ Request Body:
|
|||||||
|
|
||||||
</code>
|
</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"resourceId": 42
|
"officeId": 1,
|
||||||
|
"clientId": 1,
|
||||||
|
"loanId": 1,
|
||||||
|
"resourceId": 1
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -1542,13 +1550,28 @@ Request Body:
|
|||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
Request Body:
|
Request Body:
|
||||||
{
|
{
|
||||||
|
"locale": "en",
|
||||||
"dateFormat": "dd MMMM yyyy",
|
"dateFormat": "dd MMMM yyyy",
|
||||||
"eventDate": "07 May 2012",
|
"eventDate": "20 September 2011",
|
||||||
"note": "and event note is added"
|
"note": "and event note is added"
|
||||||
} </code>
|
}
|
||||||
<code class="method-response">
|
</code>
|
||||||
{
|
<code class="method-response">{
|
||||||
"resourceId": 37
|
"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>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -1568,7 +1591,10 @@ Content-Type: application/json
|
|||||||
No Request Body:
|
No Request Body:
|
||||||
</code>
|
</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"resourceId": 1
|
"officeId": 1,
|
||||||
|
"clientId": 1,
|
||||||
|
"loanId": 1,
|
||||||
|
"resourceId": 1
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -1749,27 +1775,20 @@ Request Body:
|
|||||||
</div>
|
</div>
|
||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
<code class="method-declaration">GET https://Domain Name/api/v1/offices</code>
|
<code class="method-declaration">GET https://Domain Name/api/v1/offices</code>
|
||||||
<code class="method-response">[ {
|
<code class="method-response">[
|
||||||
"id" : 1,
|
{
|
||||||
"name" : "Demo MFI Head Office",
|
"id": 1,
|
||||||
"externalId" : "1",
|
"name": "Head Office",
|
||||||
"openingDate" : [ 2009, 1, 1 ],
|
"nameDecorated": "Head Office",
|
||||||
"hierarchy" : "."
|
"externalId": "1",
|
||||||
}, {
|
"openingDate": [
|
||||||
"id" : 2,
|
2009,
|
||||||
"name" : "B1",
|
1,
|
||||||
"openingDate" : [ 2012, 4, 1 ],
|
1
|
||||||
"hierarchy" : ".2.",
|
],
|
||||||
"parentName" : "Demo MFI Head Office",
|
"hierarchy": "."
|
||||||
"parentId" : 1
|
}
|
||||||
}, {
|
]
|
||||||
"id" : 3,
|
|
||||||
"name" : "B2",
|
|
||||||
"openingDate" : [ 2012, 4, 4 ],
|
|
||||||
"hierarchy" : ".3.",
|
|
||||||
"parentName" : "Demo MFI Head Office",
|
|
||||||
"parentId" : 1
|
|
||||||
} ]
|
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1790,17 +1809,14 @@ Request Body:
|
|||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
<code class="method-declaration">GET https://Domain Name/api/v1/offices/template</code>
|
<code class="method-declaration">GET https://Domain Name/api/v1/offices/template</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"openingDate" : [ 2012, 5, 28 ],
|
"openingDate": [2013,2,4],
|
||||||
"allowedParents" : [ {
|
"allowedParents": [
|
||||||
"id" : 1,
|
{
|
||||||
"name" : "Demo MFI Head Office"
|
"id": 1,
|
||||||
}, {
|
"name": "Head Office",
|
||||||
"id" : 2,
|
"nameDecorated": "Head Office"
|
||||||
"name" : "B1"
|
}
|
||||||
}, {
|
]
|
||||||
"id" : 3,
|
|
||||||
"name" : "B2"
|
|
||||||
} ]
|
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -1820,11 +1836,12 @@ Request Body:
|
|||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
<code class="method-declaration">GET https://Domain Name/api/v1/offices/1</code>
|
<code class="method-declaration">GET https://Domain Name/api/v1/offices/1</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"id" : 1,
|
"id": 1,
|
||||||
"name" : "Demo MFI Head Office",
|
"name": "Head Office",
|
||||||
"externalId" : "1",
|
"nameDecorated": "Head Office",
|
||||||
"openingDate" : [ 2009, 1, 1 ],
|
"externalId": "1",
|
||||||
"hierarchy" : "."
|
"openingDate": [2009,1,1],
|
||||||
|
"hierarchy": "."
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -1876,8 +1893,8 @@ Request Body:
|
|||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"officeId": 3,
|
"officeId": 1,
|
||||||
"resourceId": 3,
|
"resourceId": 1,
|
||||||
"changes": {
|
"changes": {
|
||||||
"name": "Name is updated"
|
"name": "Name is updated"
|
||||||
}
|
}
|
||||||
@@ -1994,9 +2011,9 @@ Request Body:
|
|||||||
},
|
},
|
||||||
"annualInterestRate": 21,
|
"annualInterestRate": 21,
|
||||||
"amortizationType": {
|
"amortizationType": {
|
||||||
"id": 0,
|
"id": 1,
|
||||||
"code": "amortizationType.equal.principal",
|
"code": "amortizationType.equal.installments",
|
||||||
"value": "Equal principle payments"
|
"value": "Equal installments"
|
||||||
},
|
},
|
||||||
"interestType": {
|
"interestType": {
|
||||||
"id": 0,
|
"id": 0,
|
||||||
@@ -2243,9 +2260,9 @@ Request Body:
|
|||||||
},
|
},
|
||||||
"annualInterestRate": 21,
|
"annualInterestRate": 21,
|
||||||
"amortizationType": {
|
"amortizationType": {
|
||||||
"id": 0,
|
"id": 1,
|
||||||
"code": "amortizationType.equal.principal",
|
"code": "amortizationType.equal.installments",
|
||||||
"value": "Equal principle payments"
|
"value": "Equal installments"
|
||||||
},
|
},
|
||||||
"interestType": {
|
"interestType": {
|
||||||
"id": 0,
|
"id": 0,
|
||||||
@@ -2354,14 +2371,39 @@ Request Body:
|
|||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
<code class="method-declaration">GET https://Domain Name/api/v1/currencies</code>
|
<code class="method-declaration">GET https://Domain Name/api/v1/currencies</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"selectedCurrencyOptions" : [ {
|
"selectedCurrencyOptions": [
|
||||||
|
{
|
||||||
"code": "USD",
|
"code": "USD",
|
||||||
"name": "US Dollar",
|
"name": "US Dollar",
|
||||||
"decimalPlaces": 2,
|
"decimalPlaces": 2,
|
||||||
"displaySymbol": "$",
|
"displaySymbol": "$",
|
||||||
"nameCode": "currency.USD",
|
"nameCode": "currency.USD",
|
||||||
"displayLabel": "US Dollar ($)"
|
"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>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -2474,7 +2516,7 @@ Request Body:
|
|||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"resourceId": 2
|
"resourceId": 4
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -2498,8 +2540,12 @@ Request Body:
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"name": "MyNewCode",
|
"name": "Gender",
|
||||||
"systemDefined": false
|
"systemDefined": true
|
||||||
|
},{
|
||||||
|
"id": 3,
|
||||||
|
"name": "Education",
|
||||||
|
"systemDefined": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
</code>
|
</code>
|
||||||
@@ -2532,8 +2578,8 @@ Request Body:
|
|||||||
<p>Updates the details of a code if it is not system defined.</p>
|
<p>Updates the details of a code if it is not system defined.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
<code class="method-declaration">PUT https://Domain Name/api/v1/codes/2</code>
|
<code class="method-declaration">PUT https://Domain Name/api/v1/codes/4</code>
|
||||||
<code class="method-request">PUT codes/2
|
<code class="method-request">PUT codes/4
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
Request Body:
|
Request Body:
|
||||||
{
|
{
|
||||||
@@ -2541,7 +2587,7 @@ Request Body:
|
|||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"resourceId": 2,
|
"resourceId": 4,
|
||||||
"changes": {
|
"changes": {
|
||||||
"name": "MyNewCode(changed)"
|
"name": "MyNewCode(changed)"
|
||||||
}
|
}
|
||||||
@@ -2557,12 +2603,12 @@ Request Body:
|
|||||||
<p>Deletes a code if it is not system defined.</p>
|
<p>Deletes a code if it is not system defined.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
<code class="method-declaration">DELETE https://Domain Name/api/v1/codes/2</code>
|
<code class="method-declaration">DELETE https://Domain Name/api/v1/codes/4</code>
|
||||||
<code class="method-request">DELETE codes/2
|
<code class="method-request">DELETE codes/4
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
</code>
|
</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"resourceId": 2
|
"resourceId": 4
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -2803,7 +2849,7 @@ Request Body:
|
|||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"resourceId": 2
|
"resourceId": 1
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -2821,38 +2867,8 @@ Request Body:
|
|||||||
<code class="method-declaration">GET https://Domain Name/api/v1/charges</code>
|
<code class="method-declaration">GET https://Domain Name/api/v1/charges</code>
|
||||||
<code class="method-response">[
|
<code class="method-response">[
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 1,
|
||||||
"name": "Loan service fee",
|
"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",
|
|
||||||
"active": true,
|
"active": true,
|
||||||
"penalty": false,
|
"penalty": false,
|
||||||
"currency": {
|
"currency": {
|
||||||
@@ -2863,7 +2879,7 @@ Request Body:
|
|||||||
"nameCode": "currency.USD",
|
"nameCode": "currency.USD",
|
||||||
"displayLabel": "US Dollar ($)"
|
"displayLabel": "US Dollar ($)"
|
||||||
},
|
},
|
||||||
"amount": 456,
|
"amount": 230.560000,
|
||||||
"chargeTimeType": {
|
"chargeTimeType": {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"code": "chargeTimeType.disbursement",
|
"code": "chargeTimeType.disbursement",
|
||||||
@@ -2891,14 +2907,14 @@ Request Body:
|
|||||||
<h4>Retrieve a Charge</h4>
|
<h4>Retrieve a Charge</h4>
|
||||||
<p>Returns the details of a defined Charge.</p>
|
<p>Returns the details of a defined Charge.</p>
|
||||||
<p>Example Requests: </p>
|
<p>Example Requests: </p>
|
||||||
<div class=apiClick>charges/2</div>
|
<div class=apiClick>charges/1</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="method-example">
|
<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">{
|
<code class="method-response">{
|
||||||
"id": 2,
|
"id": 1,
|
||||||
"name": "Loan service fee",
|
"name": "Loan service fee",
|
||||||
"active": false,
|
"active": true,
|
||||||
"penalty": false,
|
"penalty": false,
|
||||||
"currency": {
|
"currency": {
|
||||||
"code": "USD",
|
"code": "USD",
|
||||||
@@ -2908,7 +2924,7 @@ Request Body:
|
|||||||
"nameCode": "currency.USD",
|
"nameCode": "currency.USD",
|
||||||
"displayLabel": "US Dollar ($)"
|
"displayLabel": "US Dollar ($)"
|
||||||
},
|
},
|
||||||
"amount": 230.56,
|
"amount": 230.560000,
|
||||||
"chargeTimeType": {
|
"chargeTimeType": {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"code": "chargeTimeType.disbursement",
|
"code": "chargeTimeType.disbursement",
|
||||||
@@ -2945,7 +2961,7 @@ Request Body:
|
|||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"resourceId": 2,
|
"resourceId": 1,
|
||||||
"changes": {
|
"changes": {
|
||||||
"name": "Loan service fee(changed)"
|
"name": "Loan service fee(changed)"
|
||||||
}
|
}
|
||||||
@@ -2961,12 +2977,12 @@ Request Body:
|
|||||||
<p>Deletes a Charge.</p>
|
<p>Deletes a Charge.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="method-example">
|
<div class="method-example">
|
||||||
<code class="method-declaration">DELETE https://Domain Name/api/v1/charges/2</code>
|
<code class="method-declaration">DELETE https://Domain Name/api/v1/charges/1</code>
|
||||||
<code class="method-request">DELETE charges/2
|
<code class="method-request">DELETE charges/1
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
</code>
|
</code>
|
||||||
<code class="method-response">{
|
<code class="method-response">{
|
||||||
"resourceId": 2
|
"resourceId": 1
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -3540,7 +3556,7 @@ Request Body:
|
|||||||
</div>
|
</div>
|
||||||
</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-section">
|
||||||
<div class="method-description">
|
<div class="method-description">
|
||||||
<h4>Verify authentication</h4>
|
<h4>Verify authentication</h4>
|
||||||
@@ -3562,9 +3578,7 @@ No Request Body
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
</code>
|
</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
|
<code class="method-request">POST authentication?username=mifos&password=fail
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
No Request Body
|
No Request Body
|
||||||
@@ -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><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 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><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><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 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>
|
<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`)
|
(`name`, `identifier`,`schema_name`)
|
||||||
VALUES
|
VALUES
|
||||||
('Default Demo Tenant', 'default' ,'mifostenant-default'),
|
('Default Demo Tenant', 'default' ,'mifostenant-default'),
|
||||||
|
('API Docs Demo', 'apidocs' ,'mifostenant-apidocs'),
|
||||||
('GK Maarg', 'gk-maarg' ,'mifostenant-gk-maarg'),
|
('GK Maarg', 'gk-maarg' ,'mifostenant-gk-maarg'),
|
||||||
('Latam Demo', 'latam' ,'mifostenant-latam'),
|
('Latam Demo', 'latam' ,'mifostenant-latam'),
|
||||||
('Bare bones Demo', 'barebones' ,'mifostenant-barebones');
|
('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);
|
||||||
+21
-3
@@ -9,8 +9,8 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Used to process the query parameters provided in a API request to see features of
|
* Used to process the query parameters provided in a API request to see
|
||||||
* the RESTful API are being asked for such as:
|
* features of the RESTful API are being asked for such as:
|
||||||
* </p>
|
* </p>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Pretty printing through pretty=true, defaults to false</li>
|
* <li>Pretty printing through pretty=true, defaults to false</li>
|
||||||
@@ -21,6 +21,23 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component
|
@Component
|
||||||
public class ApiRequestParameterHelper {
|
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) {
|
public ApiRequestJsonSerializationSettings process(final MultivaluedMap<String, String> queryParameters) {
|
||||||
|
|
||||||
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(queryParameters);
|
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(queryParameters);
|
||||||
@@ -30,6 +47,7 @@ public class ApiRequestParameterHelper {
|
|||||||
final boolean makerCheckerable = ApiParameterHelper.makerCheckerable(queryParameters);
|
final boolean makerCheckerable = ApiParameterHelper.makerCheckerable(queryParameters);
|
||||||
final boolean includeJson = ApiParameterHelper.includeJson(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);
|
this.writePlatformService.newDatatableEntry(command.entityName(), command.getApptableId(), command);
|
||||||
|
|
||||||
// FIXME - kw - need to find office and either group/client/loan that
|
return new CommandProcessingResultBuilder() //
|
||||||
// this datatable is against.
|
.withCommandId(command.commandId()) //
|
||||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(command.getApptableId()).build();
|
.withEntityId(command.getApptableId()) //
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+152
-334
@@ -37,19 +37,15 @@ import org.springframework.stereotype.Service;
|
|||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class ReadWriteNonCoreDataServiceImpl implements
|
public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataService {
|
||||||
ReadWriteNonCoreDataService {
|
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory
|
private final static Logger logger = LoggerFactory.getLogger(ReadWriteNonCoreDataServiceImpl.class);
|
||||||
.getLogger(ReadWriteNonCoreDataServiceImpl.class);
|
|
||||||
|
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final FromJsonHelper fromJsonHelper;
|
private final FromJsonHelper fromJsonHelper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ReadWriteNonCoreDataServiceImpl(
|
public ReadWriteNonCoreDataServiceImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper) {
|
||||||
final PlatformSecurityContext context,
|
|
||||||
final FromJsonHelper fromJsonHelper) {
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.fromJsonHelper = fromJsonHelper;
|
this.fromJsonHelper = fromJsonHelper;
|
||||||
}
|
}
|
||||||
@@ -67,36 +63,24 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
andClause = " and application_table_name = '" + appTable + "'";
|
andClause = " and application_table_name = '" + appTable + "'";
|
||||||
}
|
}
|
||||||
// PERMITTED datatables
|
// PERMITTED datatables
|
||||||
String sql = "select application_table_name, registered_table_name"
|
String sql = "select application_table_name, registered_table_name" + " from x_registered_table " + " where exists"
|
||||||
+ " from x_registered_table "
|
+ " (select 'f'" + " from m_appuser_role ur " + " join m_role r on r.id = ur.role_id"
|
||||||
+ " where exists"
|
+ " left join m_role_permission rp on rp.role_id = r.id" + " left join m_permission p on p.id = rp.permission_id"
|
||||||
+ " (select 'f'"
|
+ " where ur.appuser_id = " + context.authenticatedUser().getId()
|
||||||
+ " from m_appuser_role ur "
|
|
||||||
+ " join m_role r on r.id = ur.role_id"
|
|
||||||
+ " left join m_role_permission rp on rp.role_id = r.id"
|
|
||||||
+ " left join m_permission p on p.id = rp.permission_id"
|
|
||||||
+ " where ur.appuser_id = "
|
|
||||||
+ context.authenticatedUser().getId()
|
|
||||||
+ " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', registered_table_name))) "
|
+ " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', registered_table_name))) "
|
||||||
+ andClause
|
+ andClause + " order by application_table_name, registered_table_name";
|
||||||
+ " order by application_table_name, registered_table_name";
|
|
||||||
|
|
||||||
String sqlErrorMsg = "Application Table Name: " + appTable + " sql: "
|
String sqlErrorMsg = "Application Table Name: " + appTable + " sql: " + sql;
|
||||||
+ sql;
|
CachedRowSet rs = genericDataService.getCachedResultSet(sql, sqlErrorMsg);
|
||||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql,
|
|
||||||
sqlErrorMsg);
|
|
||||||
|
|
||||||
List<DatatableData> datatables = new ArrayList<DatatableData>();
|
List<DatatableData> datatables = new ArrayList<DatatableData>();
|
||||||
try {
|
try {
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
datatables.add(new DatatableData(rs
|
datatables.add(new DatatableData(rs.getString("application_table_name"), rs.getString("registered_table_name")));
|
||||||
.getString("application_table_name"), rs
|
|
||||||
.getString("registered_table_name")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg);
|
||||||
e.getMessage(), sqlErrorMsg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return datatables;
|
return datatables;
|
||||||
@@ -115,49 +99,21 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
String deletePermission = "'DELETE_" + datatable + "'";
|
String deletePermission = "'DELETE_" + datatable + "'";
|
||||||
String deletePermissionChecker = "'DELETE_" + datatable + "_CHECKER'";
|
String deletePermissionChecker = "'DELETE_" + datatable + "_CHECKER'";
|
||||||
// TODO - put in batch command later
|
// TODO - put in batch command later
|
||||||
String sql = "insert into x_registered_table (registered_table_name, application_table_name) values ('"
|
String sql = "insert into x_registered_table (registered_table_name, application_table_name) values ('" + datatable + "', '"
|
||||||
+ datatable + "', '" + appTable + "')";
|
+ appTable + "')";
|
||||||
|
|
||||||
genericDataService.updateSQL(sql, "SQL: " + sql);
|
genericDataService.updateSQL(sql, "SQL: " + sql);
|
||||||
/*
|
/*
|
||||||
* add all permissions, including checker permissions for maintenance
|
* add all permissions, including checker permissions for maintenance
|
||||||
* tasks
|
* tasks
|
||||||
*/
|
*/
|
||||||
sql = "insert into m_permission (grouping, code, action_name, entity_name, can_maker_checker) values "
|
sql = "insert into m_permission (grouping, code, action_name, entity_name, can_maker_checker) values " + "('datatable', "
|
||||||
+ "('datatable', "
|
+ createPermission + ", 'CREATE', '" + datatable + "', true)," + "('datatable', " + createPermissionChecker
|
||||||
+ createPermission
|
+ ", 'CREATE', '" + datatable + "', false)," + "('datatable', " + readPermission + ", 'READ', '" + datatable + "', false),"
|
||||||
+ ", 'CREATE', '"
|
+ "('datatable', " + updatePermission + ", 'UPDATE', '" + datatable + "', true)," + "('datatable', "
|
||||||
+ datatable
|
+ updatePermissionChecker + ", 'UPDATE', '" + datatable + "', false)," + "('datatable', " + deletePermission
|
||||||
+ "', true),"
|
+ ", 'DELETE', '" + datatable + "', true)," + "('datatable', " + deletePermissionChecker + ", 'DELETE', '" + datatable
|
||||||
+ "('datatable', "
|
+ "', false)";
|
||||||
+ createPermissionChecker
|
|
||||||
+ ", 'CREATE', '"
|
|
||||||
+ datatable
|
|
||||||
+ "', false),"
|
|
||||||
+ "('datatable', "
|
|
||||||
+ readPermission
|
|
||||||
+ ", 'READ', '"
|
|
||||||
+ datatable
|
|
||||||
+ "', false),"
|
|
||||||
+ "('datatable', "
|
|
||||||
+ updatePermission
|
|
||||||
+ ", 'UPDATE', '"
|
|
||||||
+ datatable
|
|
||||||
+ "', true),"
|
|
||||||
+ "('datatable', "
|
|
||||||
+ updatePermissionChecker
|
|
||||||
+ ", 'UPDATE', '"
|
|
||||||
+ datatable
|
|
||||||
+ "', false),"
|
|
||||||
+ "('datatable', "
|
|
||||||
+ deletePermission
|
|
||||||
+ ", 'DELETE', '"
|
|
||||||
+ datatable
|
|
||||||
+ "', true),"
|
|
||||||
+ "('datatable', "
|
|
||||||
+ deletePermissionChecker
|
|
||||||
+ ", 'DELETE', '"
|
|
||||||
+ datatable + "', false)";
|
|
||||||
|
|
||||||
genericDataService.updateSQL(sql, "SQL: " + sql);
|
genericDataService.updateSQL(sql, "SQL: " + sql);
|
||||||
}
|
}
|
||||||
@@ -166,10 +122,8 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
public void deregisterDatatable(final String datatable) {
|
public void deregisterDatatable(final String datatable) {
|
||||||
// TODO - put in batch command later
|
// TODO - put in batch command later
|
||||||
|
|
||||||
String permissionList = "('CREATE_" + datatable + "', 'CREATE_"
|
String permissionList = "('CREATE_" + datatable + "', 'CREATE_" + datatable + "_CHECKER', 'READ_" + datatable + "', 'UPDATE_"
|
||||||
+ datatable + "_CHECKER', 'READ_" + datatable + "', 'UPDATE_"
|
+ datatable + "', 'UPDATE_" + datatable + "_CHECKER', 'DELETE_" + datatable + "', 'DELETE_" + datatable + "_CHECKER')";
|
||||||
+ datatable + "', 'UPDATE_" + datatable + "_CHECKER', 'DELETE_"
|
|
||||||
+ datatable + "', 'DELETE_" + datatable + "_CHECKER')";
|
|
||||||
|
|
||||||
String sql = "delete from m_role_permission where m_role_permission.permission_id in (select id from m_permission where code in "
|
String sql = "delete from m_role_permission where m_role_permission.permission_id in (select id from m_permission where code in "
|
||||||
+ permissionList + ")";
|
+ permissionList + ")";
|
||||||
@@ -178,59 +132,43 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
sql = "delete from m_permission where code in " + permissionList;
|
sql = "delete from m_permission where code in " + permissionList;
|
||||||
genericDataService.updateSQL(sql, "SQL: " + sql);
|
genericDataService.updateSQL(sql, "SQL: " + sql);
|
||||||
|
|
||||||
sql = "delete from x_registered_table where registered_table_name = '"
|
sql = "delete from x_registered_table where registered_table_name = '" + datatable + "'";
|
||||||
+ datatable + "'";
|
|
||||||
genericDataService.updateSQL(sql, "SQL: " + sql);
|
genericDataService.updateSQL(sql, "SQL: " + sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void newDatatableEntry(final String datatable,
|
public void newDatatableEntry(final String datatable, final Long appTableId, final JsonCommand command) {
|
||||||
final Long appTableId, final JsonCommand command) {
|
String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
|
||||||
String appTable = getWithinScopeApplicationTableName(datatable,
|
|
||||||
appTableId);
|
|
||||||
|
|
||||||
List<ResultsetColumnHeader> columnHeaders = getDatatableResultsetColumnHeaders(datatable);
|
List<ResultsetColumnHeader> columnHeaders = getDatatableResultsetColumnHeaders(datatable);
|
||||||
|
|
||||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {
|
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
|
||||||
}.getType();
|
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
|
||||||
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(
|
|
||||||
typeOfMap, command.json());
|
|
||||||
|
|
||||||
String sql = getAddSql(columnHeaders, datatable, getFKField(appTable),
|
String sql = getAddSql(columnHeaders, datatable, getFKField(appTable), appTableId, dataParams);
|
||||||
appTableId, dataParams);
|
|
||||||
|
|
||||||
genericDataService.updateSQL(sql, "SQL: " + sql);
|
genericDataService.updateSQL(sql, "SQL: " + sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> updateDatatableEntryOneToOne(
|
public Map<String, Object> updateDatatableEntryOneToOne(final String datatable, final Long appTableId, final JsonCommand command) {
|
||||||
final String datatable, final Long appTableId,
|
|
||||||
final JsonCommand command) {
|
|
||||||
|
|
||||||
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable,
|
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, null);
|
||||||
appTableId, null, null);
|
|
||||||
|
|
||||||
if (grs.getData().size() == 0)
|
if (grs.getData().size() == 0) throw new DataTableNotFoundException(datatable, appTableId);
|
||||||
throw new DataTableNotFoundException(datatable, appTableId);
|
|
||||||
|
|
||||||
if (grs.getData().size() > 1)
|
if (grs.getData().size() > 1)
|
||||||
throw new PlatformDataIntegrityException(
|
throw new PlatformDataIntegrityException("error.msg.attempting.multiple.update", "Application Table: " + datatable
|
||||||
"error.msg.attempting.multiple.update",
|
+ " Foreign Key Id: " + appTableId);
|
||||||
"Application Table: " + datatable + " Foreign Key Id: "
|
|
||||||
+ appTableId);
|
|
||||||
|
|
||||||
String fkName = getFKField(getApplicationTableName(datatable));
|
String fkName = getFKField(getApplicationTableName(datatable));
|
||||||
|
|
||||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {
|
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
|
||||||
}.getType();
|
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
|
||||||
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(
|
|
||||||
typeOfMap, command.json());
|
|
||||||
|
|
||||||
final Map<String, Object> changes = getAffectedAndChangedColumns(grs,
|
final Map<String, Object> changes = getAffectedAndChangedColumns(grs, dataParams, fkName);
|
||||||
dataParams, fkName);
|
|
||||||
|
|
||||||
if (changes.size() == 0)
|
if (changes.size() == 0) return changes;
|
||||||
return changes;
|
|
||||||
|
|
||||||
String sql = getUpdateSql(datatable, fkName, appTableId, changes);
|
String sql = getUpdateSql(datatable, fkName, appTableId, changes);
|
||||||
|
|
||||||
@@ -244,26 +182,19 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> updateDatatableEntryOneToMany(
|
public Map<String, Object> updateDatatableEntryOneToMany(final String datatable, final Long appTableId, final Long datatableId,
|
||||||
final String datatable, final Long appTableId,
|
final JsonCommand command) {
|
||||||
final Long datatableId, final JsonCommand command) {
|
|
||||||
|
|
||||||
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable,
|
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, datatableId);
|
||||||
appTableId, null, datatableId);
|
|
||||||
|
|
||||||
if (grs.getData().size() == 0)
|
if (grs.getData().size() == 0) throw new DataTableNotFoundException(datatable, appTableId);
|
||||||
throw new DataTableNotFoundException(datatable, appTableId);
|
|
||||||
|
|
||||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {
|
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
|
||||||
}.getType();
|
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
|
||||||
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(
|
|
||||||
typeOfMap, command.json());
|
|
||||||
|
|
||||||
final Map<String, Object> changes = getAffectedAndChangedColumns(grs,
|
final Map<String, Object> changes = getAffectedAndChangedColumns(grs, dataParams, "id");
|
||||||
dataParams, "id");
|
|
||||||
|
|
||||||
if (changes.size() == 0)
|
if (changes.size() == 0) return changes;
|
||||||
return changes;
|
|
||||||
|
|
||||||
String sql = getUpdateSql(datatable, "id", datatableId, changes);
|
String sql = getUpdateSql(datatable, "id", datatableId, changes);
|
||||||
|
|
||||||
@@ -277,21 +208,17 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteDatatableEntries(final String datatable,
|
public void deleteDatatableEntries(final String datatable, final Long appTableId) {
|
||||||
final Long appTableId) {
|
|
||||||
|
|
||||||
String appTable = getWithinScopeApplicationTableName(datatable,
|
String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
|
||||||
appTableId);
|
|
||||||
|
|
||||||
String sql = getDeleteEntriesSql(datatable, getFKField(appTable),
|
String sql = getDeleteEntriesSql(datatable, getFKField(appTable), appTableId);
|
||||||
appTableId);
|
|
||||||
|
|
||||||
genericDataService.updateSQL(sql, "SQL: " + sql);
|
genericDataService.updateSQL(sql, "SQL: " + sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteDatatableEntry(final String datatable,
|
public void deleteDatatableEntry(final String datatable, final Long appTableId, final Long datatableId) {
|
||||||
final Long appTableId, final Long datatableId) {
|
|
||||||
|
|
||||||
getWithinScopeApplicationTableName(datatable, appTableId);
|
getWithinScopeApplicationTableName(datatable, appTableId);
|
||||||
|
|
||||||
@@ -301,12 +228,10 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GenericResultsetData retrieveDataTableGenericResultSet(
|
public GenericResultsetData retrieveDataTableGenericResultSet(final String datatable, final Long appTableId, final String order,
|
||||||
final String datatable, final Long appTableId, final String order,
|
|
||||||
final Long id) {
|
final Long id) {
|
||||||
|
|
||||||
String appTable = getWithinScopeApplicationTableName(datatable,
|
String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
|
||||||
appTableId);
|
|
||||||
|
|
||||||
List<ResultsetColumnHeader> columnHeaders = getDatatableResultsetColumnHeaders(datatable);
|
List<ResultsetColumnHeader> columnHeaders = getDatatableResultsetColumnHeaders(datatable);
|
||||||
|
|
||||||
@@ -315,33 +240,27 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
// id only used for reading a specific entry in a one to many datatable
|
// id only used for reading a specific entry in a one to many datatable
|
||||||
// (when updating)
|
// (when updating)
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
sql = sql + "select * from `" + datatable + "` where "
|
sql = sql + "select * from `" + datatable + "` where " + getFKField(appTable) + " = " + appTableId;
|
||||||
+ getFKField(appTable) + " = " + appTableId;
|
|
||||||
} else {
|
} else {
|
||||||
sql = sql + "select * from `" + datatable + "` where id = " + id;
|
sql = sql + "select * from `" + datatable + "` where id = " + id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order != null)
|
if (order != null) sql = sql + " order by " + order;
|
||||||
sql = sql + " order by " + order;
|
|
||||||
|
|
||||||
List<ResultsetDataRow> result = fillDatatableResultSetDataRows(sql);
|
List<ResultsetDataRow> result = fillDatatableResultSetDataRows(sql);
|
||||||
|
|
||||||
return new GenericResultsetData(columnHeaders, result);
|
return new GenericResultsetData(columnHeaders, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkMainResourceExistsWithinScope(final String appTable,
|
private void checkMainResourceExistsWithinScope(final String appTable, final Long appTableId) {
|
||||||
final Long appTableId) {
|
|
||||||
|
|
||||||
String unscopedSql = "select t.id from `" + appTable
|
String unscopedSql = "select t.id from `" + appTable + "` t ${dataScopeCriteria} where t.id = " + appTableId;
|
||||||
+ "` t ${dataScopeCriteria} where t.id = " + appTableId;
|
|
||||||
|
|
||||||
String sql = dataScopedSQL(unscopedSql, appTable);
|
String sql = dataScopedSQL(unscopedSql, appTable);
|
||||||
|
|
||||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : "
|
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql);
|
||||||
+ sql);
|
|
||||||
|
|
||||||
if (rs.size() == 0)
|
if (rs.size() == 0) throw new DataTableNotFoundException(appTable, appTableId);
|
||||||
throw new DataTableNotFoundException(appTable, appTableId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String dataScopedSQL(final String unscopedSQL, final String appTable) {
|
private String dataScopedSQL(final String unscopedSQL, final String appTable) {
|
||||||
@@ -356,45 +275,33 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
|
|
||||||
AppUser currentUser = context.authenticatedUser();
|
AppUser currentUser = context.authenticatedUser();
|
||||||
if (appTable.equalsIgnoreCase("m_client")) {
|
if (appTable.equalsIgnoreCase("m_client")) {
|
||||||
dataScopeCriteria = " join m_office o on o.id = t.office_id and o.hierarchy like '"
|
dataScopeCriteria = " join m_office o on o.id = t.office_id and o.hierarchy like '" + currentUser.getOffice().getHierarchy()
|
||||||
+ currentUser.getOffice().getHierarchy() + "%'";
|
+ "%'";
|
||||||
}
|
}
|
||||||
if (appTable.equalsIgnoreCase("m_loan")) {
|
if (appTable.equalsIgnoreCase("m_loan")) {
|
||||||
dataScopeCriteria = " join m_client c on c.id = t.client_id "
|
dataScopeCriteria = " join m_client c on c.id = t.client_id " + " join m_office o on o.id = c.office_id and o.hierarchy like '"
|
||||||
+ " join m_office o on o.id = c.office_id and o.hierarchy like '"
|
|
||||||
+ currentUser.getOffice().getHierarchy() + "%'";
|
+ currentUser.getOffice().getHierarchy() + "%'";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataScopeCriteria == null) {
|
if (dataScopeCriteria == null) { throw new PlatformDataIntegrityException("error.msg.invalid.dataScopeCriteria",
|
||||||
throw new PlatformDataIntegrityException(
|
"Application Table: " + appTable + " not catered for in data Scoping"); }
|
||||||
"error.msg.invalid.dataScopeCriteria",
|
|
||||||
"Application Table: " + appTable
|
|
||||||
+ " not catered for in data Scoping");
|
|
||||||
}
|
|
||||||
|
|
||||||
return genericDataService.replace(unscopedSQL, "${dataScopeCriteria}",
|
return genericDataService.replace(unscopedSQL, "${dataScopeCriteria}", dataScopeCriteria);
|
||||||
dataScopeCriteria);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateAppTable(final String appTable) {
|
private void validateAppTable(final String appTable) {
|
||||||
|
|
||||||
if (appTable.equalsIgnoreCase("m_client"))
|
if (appTable.equalsIgnoreCase("m_client")) return;
|
||||||
return;
|
if (appTable.equalsIgnoreCase("m_loan")) return;
|
||||||
if (appTable.equalsIgnoreCase("m_loan"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
throw new PlatformDataIntegrityException(
|
throw new PlatformDataIntegrityException("error.msg.invalid.application.table", "Invalid Application Table: " + appTable);
|
||||||
"error.msg.invalid.application.table",
|
|
||||||
"Invalid Application Table: " + appTable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ResultsetDataRow> fillDatatableResultSetDataRows(
|
private List<ResultsetDataRow> fillDatatableResultSetDataRows(final String sql) {
|
||||||
final String sql) {
|
|
||||||
|
|
||||||
String sqlErrorMsg = "Sql: " + sql;
|
String sqlErrorMsg = "Sql: " + sql;
|
||||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql,
|
CachedRowSet rs = genericDataService.getCachedResultSet(sql, sqlErrorMsg);
|
||||||
sqlErrorMsg);
|
|
||||||
|
|
||||||
List<ResultsetDataRow> resultsetDataRows = new ArrayList<ResultsetDataRow>();
|
List<ResultsetDataRow> resultsetDataRows = new ArrayList<ResultsetDataRow>();
|
||||||
|
|
||||||
@@ -420,21 +327,16 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
|
|
||||||
return resultsetDataRows;
|
return resultsetDataRows;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg);
|
||||||
e.getMessage(), sqlErrorMsg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getWithinScopeApplicationTableName(final String datatable,
|
private String getWithinScopeApplicationTableName(final String datatable, final Long appTableId) {
|
||||||
final Long appTableId) {
|
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'";
|
||||||
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '"
|
|
||||||
+ datatable + "'";
|
|
||||||
|
|
||||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : "
|
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql);
|
||||||
+ sql);
|
|
||||||
|
|
||||||
if (rs.size() == 0)
|
if (rs.size() == 0) throw new DataTableNotFoundException(datatable);
|
||||||
throw new DataTableNotFoundException(datatable);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
rs.next();
|
rs.next();
|
||||||
@@ -444,29 +346,24 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
|
|
||||||
return appTable;
|
return appTable;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage());
|
||||||
e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getApplicationTableName(final String datatable) {
|
private String getApplicationTableName(final String datatable) {
|
||||||
// TODO - only used for update... can probably remove this after as its
|
// TODO - only used for update... can probably remove this after as its
|
||||||
// a reread
|
// a reread
|
||||||
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '"
|
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'";
|
||||||
+ datatable + "'";
|
|
||||||
|
|
||||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : "
|
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql);
|
||||||
+ sql);
|
|
||||||
|
|
||||||
if (rs.size() == 0)
|
if (rs.size() == 0) throw new DataTableNotFoundException(datatable);
|
||||||
throw new DataTableNotFoundException(datatable);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
rs.next();
|
rs.next();
|
||||||
return rs.getString("application_table_name");
|
return rs.getString("application_table_name");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage());
|
||||||
e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,21 +375,17 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
private CachedRowSet getDatatableMetaData(final String datatable) {
|
private CachedRowSet getDatatableMetaData(final String datatable) {
|
||||||
|
|
||||||
String sql = "select COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMN_KEY"
|
String sql = "select COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMN_KEY"
|
||||||
+ " from INFORMATION_SCHEMA.COLUMNS "
|
+ " from INFORMATION_SCHEMA.COLUMNS " + " where TABLE_SCHEMA = schema() and TABLE_NAME = '" + datatable
|
||||||
+ " where TABLE_SCHEMA = schema() and TABLE_NAME = '"
|
+ "'order by ORDINAL_POSITION";
|
||||||
+ datatable + "'order by ORDINAL_POSITION";
|
|
||||||
|
|
||||||
CachedRowSet columnDefinitions = genericDataService.getCachedResultSet(
|
CachedRowSet columnDefinitions = genericDataService.getCachedResultSet(sql, "SQL: " + sql);
|
||||||
sql, "SQL: " + sql);
|
|
||||||
|
|
||||||
if (columnDefinitions.size() > 0)
|
if (columnDefinitions.size() > 0) return columnDefinitions;
|
||||||
return columnDefinitions;
|
|
||||||
|
|
||||||
throw new DataTableNotFoundException(datatable);
|
throw new DataTableNotFoundException(datatable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ResultsetColumnHeader> getDatatableResultsetColumnHeaders(
|
private List<ResultsetColumnHeader> getDatatableResultsetColumnHeaders(final String datatable) {
|
||||||
final String datatable) {
|
|
||||||
|
|
||||||
CachedRowSet columnDefinitions = getDatatableMetaData(datatable);
|
CachedRowSet columnDefinitions = getDatatableMetaData(datatable);
|
||||||
|
|
||||||
@@ -517,20 +410,15 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
else
|
else
|
||||||
rsch.setColumnPrimaryKey(false);
|
rsch.setColumnPrimaryKey(false);
|
||||||
|
|
||||||
Long columnLength = columnDefinitions
|
Long columnLength = columnDefinitions.getLong("CHARACTER_MAXIMUM_LENGTH");
|
||||||
.getLong("CHARACTER_MAXIMUM_LENGTH");
|
if (columnLength > 0) rsch.setColumnLength(columnDefinitions.getLong("CHARACTER_MAXIMUM_LENGTH"));
|
||||||
if (columnLength > 0)
|
|
||||||
rsch.setColumnLength(columnDefinitions
|
|
||||||
.getLong("CHARACTER_MAXIMUM_LENGTH"));
|
|
||||||
|
|
||||||
rsch.setColumnType(columnDefinitions.getString("DATA_TYPE"));
|
rsch.setColumnType(columnDefinitions.getString("DATA_TYPE"));
|
||||||
|
|
||||||
/* look for codes */
|
/* look for codes */
|
||||||
if (rsch.getColumnType().equalsIgnoreCase("varchar"))
|
if (rsch.getColumnType().equalsIgnoreCase("varchar")) addCodesValueIfNecessary(rsch, "_cv");
|
||||||
addCodesValueIfNecessary(rsch, "_cv");
|
|
||||||
|
|
||||||
if (rsch.getColumnType().equalsIgnoreCase("int"))
|
if (rsch.getColumnType().equalsIgnoreCase("int")) addCodesValueIfNecessary(rsch, "_cd");
|
||||||
addCodesValueIfNecessary(rsch, "_cd");
|
|
||||||
|
|
||||||
rsch.setColumnDisplayType();
|
rsch.setColumnDisplayType();
|
||||||
|
|
||||||
@@ -540,46 +428,36 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
return columnHeaders;
|
return columnHeaders;
|
||||||
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage());
|
||||||
e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCodesValueIfNecessary(final ResultsetColumnHeader rsch,
|
private void addCodesValueIfNecessary(final ResultsetColumnHeader rsch, final String code_suffix) {
|
||||||
final String code_suffix) {
|
|
||||||
int codePosition = rsch.getColumnName().indexOf(code_suffix);
|
int codePosition = rsch.getColumnName().indexOf(code_suffix);
|
||||||
if (codePosition > 0) {
|
if (codePosition > 0) {
|
||||||
String codeName = rsch.getColumnName().substring(0, codePosition);
|
String codeName = rsch.getColumnName().substring(0, codePosition);
|
||||||
|
|
||||||
String sql = "select v.id, v.code_value from m_code m "
|
String sql = "select v.id, v.code_value from m_code m " + " join m_code_value v on v.code_id = m.id "
|
||||||
+ " join m_code_value v on v.code_id = m.id "
|
+ " where m.code_name = '" + codeName + "' order by v.order_position, v.id";
|
||||||
+ " where m.code_name = '" + codeName
|
|
||||||
+ "' order by v.order_position, v.id";
|
|
||||||
|
|
||||||
CachedRowSet rsValues = genericDataService.getCachedResultSet(sql,
|
CachedRowSet rsValues = genericDataService.getCachedResultSet(sql, "SQL: " + sql);
|
||||||
"SQL: " + sql);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (rsValues.next()) {
|
while (rsValues.next()) {
|
||||||
rsch.getColumnValues().add(
|
rsch.getColumnValues().add(new ResultsetColumnValue(rsValues.getInt("id"), rsValues.getString("code_value")));
|
||||||
new ResultsetColumnValue(rsValues.getInt("id"),
|
|
||||||
rsValues.getString("code_value")));
|
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage());
|
||||||
e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getAddSql(final List<ResultsetColumnHeader> columnHeaders,
|
private String getAddSql(final List<ResultsetColumnHeader> columnHeaders, final String datatable, final String fkName,
|
||||||
final String datatable, final String fkName, final Long appTableId,
|
final Long appTableId, final Map<String, String> queryParams) {
|
||||||
final Map<String, String> queryParams) {
|
|
||||||
|
|
||||||
final Map<String, String> affectedColumns = getAffectedColumns(
|
final Map<String, String> affectedColumns = getAffectedColumns(columnHeaders, queryParams, fkName);
|
||||||
columnHeaders, queryParams, fkName);
|
|
||||||
|
|
||||||
String pValueWrite = "";
|
String pValueWrite = "";
|
||||||
String addSql = "";
|
String addSql = "";
|
||||||
@@ -595,24 +473,20 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
if (StringUtils.isEmpty(pValue)) {
|
if (StringUtils.isEmpty(pValue)) {
|
||||||
pValueWrite = "null";
|
pValueWrite = "null";
|
||||||
} else {
|
} else {
|
||||||
pValueWrite = singleQuote
|
pValueWrite = singleQuote + genericDataService.replace(pValue, singleQuote, singleQuote + singleQuote) + singleQuote;
|
||||||
+ genericDataService.replace(pValue, singleQuote,
|
|
||||||
singleQuote + singleQuote) + singleQuote;
|
|
||||||
}
|
}
|
||||||
columnName = "`" + key + "`";
|
columnName = "`" + key + "`";
|
||||||
insertColumns += ", " + columnName;
|
insertColumns += ", " + columnName;
|
||||||
selectColumns += "," + pValueWrite + " as " + columnName;
|
selectColumns += "," + pValueWrite + " as " + columnName;
|
||||||
}
|
}
|
||||||
|
|
||||||
addSql = "insert into `" + datatable + "` (`" + fkName + "` "
|
addSql = "insert into `" + datatable + "` (`" + fkName + "` " + insertColumns + ")" + " select " + appTableId + " as id"
|
||||||
+ insertColumns + ")" + " select " + appTableId + " as id"
|
|
||||||
+ selectColumns;
|
+ selectColumns;
|
||||||
|
|
||||||
return addSql;
|
return addSql;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUpdateSql(final String datatable,
|
private String getUpdateSql(final String datatable, final String keyFieldName, final Long keyFieldValue,
|
||||||
final String keyFieldName, final Long keyFieldValue,
|
|
||||||
final Map<String, Object> changedColumns) {
|
final Map<String, Object> changedColumns) {
|
||||||
|
|
||||||
// just updating fields that have changed since pre-update read - though
|
// just updating fields that have changed since pre-update read - though
|
||||||
@@ -622,8 +496,7 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
// completeness but its okay to take this risk with additional fields
|
// completeness but its okay to take this risk with additional fields
|
||||||
// data
|
// data
|
||||||
|
|
||||||
if (changedColumns.size() == 0)
|
if (changedColumns.size() == 0) return null;
|
||||||
return null;
|
|
||||||
|
|
||||||
String pValue = null;
|
String pValue = null;
|
||||||
String pValueWrite = "";
|
String pValueWrite = "";
|
||||||
@@ -643,9 +516,7 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
if (StringUtils.isEmpty(pValue)) {
|
if (StringUtils.isEmpty(pValue)) {
|
||||||
pValueWrite = "null";
|
pValueWrite = "null";
|
||||||
} else {
|
} else {
|
||||||
pValueWrite = singleQuote
|
pValueWrite = singleQuote + genericDataService.replace(pValue, singleQuote, singleQuote + singleQuote) + singleQuote;
|
||||||
+ genericDataService.replace(pValue, singleQuote,
|
|
||||||
singleQuote + singleQuote) + singleQuote;
|
|
||||||
}
|
}
|
||||||
sql += "`" + key + "` = " + pValueWrite;
|
sql += "`" + key + "` = " + pValueWrite;
|
||||||
}
|
}
|
||||||
@@ -655,12 +526,10 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Object> getAffectedAndChangedColumns(
|
private Map<String, Object> getAffectedAndChangedColumns(final GenericResultsetData grs, final Map<String, String> queryParams,
|
||||||
final GenericResultsetData grs,
|
final String fkName) {
|
||||||
final Map<String, String> queryParams, final String fkName) {
|
|
||||||
|
|
||||||
Map<String, String> affectedColumns = getAffectedColumns(
|
Map<String, String> affectedColumns = getAffectedColumns(grs.getColumnHeaders(), queryParams, fkName);
|
||||||
grs.getColumnHeaders(), queryParams, fkName);
|
|
||||||
Map<String, Object> affectedAndChangedColumns = new HashMap<String, Object>();
|
Map<String, Object> affectedAndChangedColumns = new HashMap<String, Object>();
|
||||||
String columnValue;
|
String columnValue;
|
||||||
|
|
||||||
@@ -674,8 +543,7 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
return affectedAndChangedColumns;
|
return affectedAndChangedColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean columnChanged(final String key, final String keyValue,
|
private boolean columnChanged(final String key, final String keyValue, final GenericResultsetData grs) {
|
||||||
final GenericResultsetData grs) {
|
|
||||||
|
|
||||||
List<String> columnValues = grs.getData().get(0).getRow();
|
List<String> columnValues = grs.getData().get(0).getRow();
|
||||||
|
|
||||||
@@ -696,20 +564,16 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new PlatformDataIntegrityException(
|
throw new PlatformDataIntegrityException("error.msg.invalid.columnName", "Parameter Column Name: " + key + " not found");
|
||||||
"error.msg.invalid.columnName", "Parameter Column Name: " + key
|
|
||||||
+ " not found");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, String> getAffectedColumns(
|
private Map<String, String> getAffectedColumns(final List<ResultsetColumnHeader> columnHeaders, final Map<String, String> queryParams,
|
||||||
final List<ResultsetColumnHeader> columnHeaders,
|
final String keyFieldName) {
|
||||||
final Map<String, String> queryParams, final String keyFieldName) {
|
|
||||||
|
|
||||||
String dateFormat = queryParams.get("dateFormat");
|
String dateFormat = queryParams.get("dateFormat");
|
||||||
Locale clientApplicationLocale = null;
|
Locale clientApplicationLocale = null;
|
||||||
String localeQueryParam = queryParams.get("locale");
|
String localeQueryParam = queryParams.get("locale");
|
||||||
if (!(StringUtils.isBlank(localeQueryParam)))
|
if (!(StringUtils.isBlank(localeQueryParam))) clientApplicationLocale = new Locale(queryParams.get("locale"));
|
||||||
clientApplicationLocale = new Locale(queryParams.get("locale"));
|
|
||||||
|
|
||||||
String underscore = "_";
|
String underscore = "_";
|
||||||
String space = " ";
|
String space = " ";
|
||||||
@@ -724,134 +588,95 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
// ignores id and foreign key fields
|
// ignores id and foreign key fields
|
||||||
// also ignores locale and dateformat fields that are used for
|
// also ignores locale and dateformat fields that are used for
|
||||||
// validating numeric and date data
|
// validating numeric and date data
|
||||||
if (!((key.equalsIgnoreCase("id"))
|
if (!((key.equalsIgnoreCase("id")) || (key.equalsIgnoreCase(keyFieldName)) || (key.equals("locale")) || (key
|
||||||
|| (key.equalsIgnoreCase(keyFieldName))
|
.equals("dateFormat")))) {
|
||||||
|| (key.equals("locale")) || (key.equals("dateFormat")))) {
|
|
||||||
notFound = true;
|
notFound = true;
|
||||||
// matches incoming fields with and without underscores (spaces
|
// matches incoming fields with and without underscores (spaces
|
||||||
// and underscores considered the same)
|
// and underscores considered the same)
|
||||||
queryParamColumnUnderscored = genericDataService.replace(key,
|
queryParamColumnUnderscored = genericDataService.replace(key, space, underscore);
|
||||||
space, underscore);
|
|
||||||
for (ResultsetColumnHeader columnHeader : columnHeaders) {
|
for (ResultsetColumnHeader columnHeader : columnHeaders) {
|
||||||
if (notFound) {
|
if (notFound) {
|
||||||
columnHeaderUnderscored = genericDataService
|
columnHeaderUnderscored = genericDataService.replace(columnHeader.getColumnName(), space, underscore);
|
||||||
.replace(columnHeader.getColumnName(), space,
|
if (queryParamColumnUnderscored.equalsIgnoreCase(columnHeaderUnderscored)) {
|
||||||
underscore);
|
|
||||||
if (queryParamColumnUnderscored
|
|
||||||
.equalsIgnoreCase(columnHeaderUnderscored)) {
|
|
||||||
pValue = queryParams.get(key);
|
pValue = queryParams.get(key);
|
||||||
pValue = validateColumn(columnHeader, pValue,
|
pValue = validateColumn(columnHeader, pValue, dateFormat, clientApplicationLocale);
|
||||||
dateFormat, clientApplicationLocale);
|
affectedColumns.put(columnHeader.getColumnName(), pValue);
|
||||||
affectedColumns.put(columnHeader.getColumnName(),
|
|
||||||
pValue);
|
|
||||||
notFound = false;
|
notFound = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (notFound) {
|
if (notFound) { throw new PlatformDataIntegrityException("error.msg.column.not.found", "Column: " + key + " Not Found"); }
|
||||||
throw new PlatformDataIntegrityException(
|
|
||||||
"error.msg.column.not.found", "Column: " + key
|
|
||||||
+ " Not Found");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return affectedColumns;
|
return affectedColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String validateColumn(final ResultsetColumnHeader columnHeader,
|
private String validateColumn(final ResultsetColumnHeader columnHeader, final String pValue, final String dateFormat,
|
||||||
final String pValue, final String dateFormat,
|
|
||||||
final Locale clientApplicationLocale) {
|
final Locale clientApplicationLocale) {
|
||||||
|
|
||||||
String paramValue = pValue;
|
String paramValue = pValue;
|
||||||
if ((columnHeader.getColumnDisplayType().equals("DATE"))
|
if ((columnHeader.getColumnDisplayType().equals("DATE")) || (columnHeader.getColumnDisplayType().equals("INTEGER"))
|
||||||
|| (columnHeader.getColumnDisplayType().equals("INTEGER"))
|
|| (columnHeader.getColumnDisplayType().equals("DECIMAL"))) paramValue = paramValue.trim();
|
||||||
|| (columnHeader.getColumnDisplayType().equals("DECIMAL")))
|
|
||||||
paramValue = paramValue.trim();
|
|
||||||
|
|
||||||
if ((StringUtils.isEmpty(paramValue))
|
if ((StringUtils.isEmpty(paramValue)) && (!(columnHeader.isColumnNullable()))) {
|
||||||
&& (!(columnHeader.isColumnNullable()))) {
|
|
||||||
|
|
||||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
ApiParameterError error = ApiParameterError.parameterError(
|
ApiParameterError error = ApiParameterError.parameterError("error.msg.column.mandatory", "Mandatory",
|
||||||
"error.msg.column.mandatory", "Mandatory",
|
|
||||||
columnHeader.getColumnName());
|
columnHeader.getColumnName());
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
throw new PlatformApiDataValidationException(
|
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||||
"validation.msg.validation.errors.exist",
|
dataValidationErrors);
|
||||||
"Validation errors exist.", dataValidationErrors);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StringUtils.isEmpty(paramValue)) {
|
if (!StringUtils.isEmpty(paramValue)) {
|
||||||
|
|
||||||
if (columnHeader.getColumnValues().size() > 0) {
|
if (columnHeader.getColumnValues().size() > 0) {
|
||||||
// match code value or id
|
// match code value or id
|
||||||
List<ResultsetColumnValue> allowedValues = columnHeader
|
List<ResultsetColumnValue> allowedValues = columnHeader.getColumnValues();
|
||||||
.getColumnValues();
|
|
||||||
if (columnHeader.getColumnDisplayType().equals("CODEVALUE")) {
|
if (columnHeader.getColumnDisplayType().equals("CODEVALUE")) {
|
||||||
for (ResultsetColumnValue allowedValue : allowedValues) {
|
for (ResultsetColumnValue allowedValue : allowedValues) {
|
||||||
if (paramValue
|
if (paramValue.equalsIgnoreCase(allowedValue.getValue())) return paramValue;
|
||||||
.equalsIgnoreCase(allowedValue.getValue()))
|
|
||||||
return paramValue;
|
|
||||||
}
|
}
|
||||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
ApiParameterError error = ApiParameterError.parameterError(
|
ApiParameterError error = ApiParameterError.parameterError("error.msg.invalid.columnValue",
|
||||||
"error.msg.invalid.columnValue",
|
"Value not found in Allowed Value list", columnHeader.getColumnName(), paramValue);
|
||||||
"Value not found in Allowed Value list",
|
|
||||||
columnHeader.getColumnName(), paramValue);
|
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
throw new PlatformApiDataValidationException(
|
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||||
"validation.msg.validation.errors.exist",
|
dataValidationErrors);
|
||||||
"Validation errors exist.", dataValidationErrors);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (columnHeader.getColumnDisplayType().equals("CODELOOKUP")) {
|
if (columnHeader.getColumnDisplayType().equals("CODELOOKUP")) {
|
||||||
for (ResultsetColumnValue allowedValue : allowedValues) {
|
for (ResultsetColumnValue allowedValue : allowedValues) {
|
||||||
if (paramValue.equals(Integer.toString(allowedValue
|
if (paramValue.equals(Integer.toString(allowedValue.getId()))) return paramValue;
|
||||||
.getId())))
|
|
||||||
return paramValue;
|
|
||||||
}
|
}
|
||||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
ApiParameterError error = ApiParameterError.parameterError(
|
ApiParameterError error = ApiParameterError.parameterError("error.msg.invalid.columnValue",
|
||||||
"error.msg.invalid.columnValue",
|
"Value not found in Allowed Value list", columnHeader.getColumnName(), paramValue);
|
||||||
"Value not found in Allowed Value list",
|
|
||||||
columnHeader.getColumnName(), paramValue);
|
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
throw new PlatformApiDataValidationException(
|
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||||
"validation.msg.validation.errors.exist",
|
dataValidationErrors);
|
||||||
"Validation errors exist.", dataValidationErrors);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new PlatformDataIntegrityException(
|
throw new PlatformDataIntegrityException("error.msg.invalid.columnType.", "Code: " + columnHeader.getColumnName()
|
||||||
"error.msg.invalid.columnType.", "Code: "
|
+ " - Invalid Type " + columnHeader.getColumnType() + " (neither varchar nor int)");
|
||||||
+ columnHeader.getColumnName()
|
|
||||||
+ " - Invalid Type "
|
|
||||||
+ columnHeader.getColumnType()
|
|
||||||
+ " (neither varchar nor int)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonParserHelper helper = new JsonParserHelper();
|
JsonParserHelper helper = new JsonParserHelper();
|
||||||
|
|
||||||
if (columnHeader.getColumnDisplayType().equals("DATE")) {
|
if (columnHeader.getColumnDisplayType().equals("DATE")) {
|
||||||
LocalDate tmpDate = helper.convertFrom(paramValue,
|
LocalDate tmpDate = helper.convertFrom(paramValue, columnHeader.getColumnName(), dateFormat, clientApplicationLocale);
|
||||||
columnHeader.getColumnName(), dateFormat,
|
if (tmpDate == null) return null;
|
||||||
clientApplicationLocale);
|
|
||||||
if (tmpDate == null)
|
|
||||||
return null;
|
|
||||||
return tmpDate.toString();
|
return tmpDate.toString();
|
||||||
}
|
}
|
||||||
if (columnHeader.getColumnDisplayType().equals("INTEGER")) {
|
if (columnHeader.getColumnDisplayType().equals("INTEGER")) {
|
||||||
Integer tmpInt = helper.convertToInteger(paramValue,
|
Integer tmpInt = helper.convertToInteger(paramValue, columnHeader.getColumnName(), clientApplicationLocale);
|
||||||
columnHeader.getColumnName(), clientApplicationLocale);
|
if (tmpInt == null) return null;
|
||||||
if (tmpInt == null)
|
|
||||||
return null;
|
|
||||||
return tmpInt.toString();
|
return tmpInt.toString();
|
||||||
}
|
}
|
||||||
if (columnHeader.getColumnDisplayType().equals("DECIMAL")) {
|
if (columnHeader.getColumnDisplayType().equals("DECIMAL")) {
|
||||||
BigDecimal tmpDecimal = helper.convertFrom(paramValue,
|
BigDecimal tmpDecimal = helper.convertFrom(paramValue, columnHeader.getColumnName(), clientApplicationLocale);
|
||||||
columnHeader.getColumnName(), clientApplicationLocale);
|
if (tmpDecimal == null) return null;
|
||||||
if (tmpDecimal == null)
|
|
||||||
return null;
|
|
||||||
return tmpDecimal.toString();
|
return tmpDecimal.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -860,33 +685,26 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
|||||||
return paramValue;
|
return paramValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDeleteEntriesSql(final String datatable,
|
private String getDeleteEntriesSql(final String datatable, final String FKField, final Long appTableId) {
|
||||||
final String FKField, final Long appTableId) {
|
|
||||||
|
|
||||||
return "delete from `" + datatable + "` where `" + FKField + "` = "
|
return "delete from `" + datatable + "` where `" + FKField + "` = " + appTableId;
|
||||||
+ appTableId;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDeleteEntrySql(final String datatable,
|
private String getDeleteEntrySql(final String datatable, final Long datatableId) {
|
||||||
final Long datatableId) {
|
|
||||||
|
|
||||||
return "delete from `" + datatable + "` where `id` = " + datatableId;
|
return "delete from `" + datatable + "` where `id` = " + datatableId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean notTheSame(final String currValue, final String pValue) {
|
private boolean notTheSame(final String currValue, final String pValue) {
|
||||||
if (StringUtils.isEmpty(currValue) && StringUtils.isEmpty(pValue))
|
if (StringUtils.isEmpty(currValue) && StringUtils.isEmpty(pValue)) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
if (StringUtils.isEmpty(currValue))
|
if (StringUtils.isEmpty(currValue)) return true;
|
||||||
return true;
|
|
||||||
|
|
||||||
if (StringUtils.isEmpty(pValue))
|
if (StringUtils.isEmpty(pValue)) return true;
|
||||||
return true;
|
|
||||||
|
|
||||||
if (currValue.equals(pValue))
|
if (currValue.equals(pValue)) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-3
@@ -76,10 +76,11 @@ public class LoansApiResource {
|
|||||||
"annualInterestRate", "repaymentFrequencyType", "interestRateFrequencyType", "amortizationType", "interestType",
|
"annualInterestRate", "repaymentFrequencyType", "interestRateFrequencyType", "amortizationType", "interestType",
|
||||||
"interestCalculationPeriodType", "submittedOnDate", "approvedOnDate", "expectedDisbursementDate", "actualDisbursementDate",
|
"interestCalculationPeriodType", "submittedOnDate", "approvedOnDate", "expectedDisbursementDate", "actualDisbursementDate",
|
||||||
"expectedFirstRepaymentOnDate", "interestChargedFromDate", "closedOnDate", "expectedMaturityDate", "status",
|
"expectedFirstRepaymentOnDate", "interestChargedFromDate", "closedOnDate", "expectedMaturityDate", "status",
|
||||||
"lifeCycleStatusDate", "repaymentSchedule", "transactions", "permissions", "convenienceData", "charges", "productOptions",
|
"lifeCycleStatusDate", "repaymentSchedule", "transactions", "permissions", "convenienceData", "charges", "guarantor", "productOptions",
|
||||||
"amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions", "repaymentFrequencyTypeOptions",
|
"amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions", "repaymentFrequencyTypeOptions",
|
||||||
"interestRateFrequencyTypeOptions", "fundOptions", "repaymentStrategyOptions", "chargeOptions", "loanOfficerId",
|
"interestRateFrequencyTypeOptions", "fundOptions", "repaymentStrategyOptions", "chargeOptions", "loanOfficerId",
|
||||||
"loanOfficerName", "loanOfficerOptions", "chargeTemplate"));
|
"loanOfficerName", "loanOfficerOptions", "chargeTemplate", "transactionProcessingStrategyId",
|
||||||
|
"termFrequency", "termPeriodFrequencyType"));
|
||||||
|
|
||||||
private final String resourceNameForPermissions = "LOAN";
|
private final String resourceNameForPermissions = "LOAN";
|
||||||
|
|
||||||
@@ -201,6 +202,7 @@ public class LoansApiResource {
|
|||||||
Collection<LoanChargeData> charges = null;
|
Collection<LoanChargeData> charges = null;
|
||||||
Collection<GuarantorData> guarantors = null;
|
Collection<GuarantorData> guarantors = null;
|
||||||
|
|
||||||
|
final Set<String> mandatoryResponseParameters = new HashSet<String>();
|
||||||
boolean convenienceDataRequired = false;
|
boolean convenienceDataRequired = false;
|
||||||
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||||
if (!associationParameters.isEmpty()) {
|
if (!associationParameters.isEmpty()) {
|
||||||
@@ -211,6 +213,7 @@ public class LoansApiResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (associationParameters.contains("guarantor")) {
|
if (associationParameters.contains("guarantor")) {
|
||||||
|
mandatoryResponseParameters.add("guarantor");
|
||||||
guarantors = this.guarantorReadPlatformService.retrieveGuarantorsForLoan(loanId);
|
guarantors = this.guarantorReadPlatformService.retrieveGuarantorsForLoan(loanId);
|
||||||
if (CollectionUtils.isEmpty(guarantors)) {
|
if (CollectionUtils.isEmpty(guarantors)) {
|
||||||
guarantors = null; // set back to null so doesn't appear in JSON
|
guarantors = null; // set back to null so doesn't appear in JSON
|
||||||
@@ -218,6 +221,7 @@ public class LoansApiResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (associationParameters.contains("transactions")) {
|
if (associationParameters.contains("transactions")) {
|
||||||
|
mandatoryResponseParameters.add("transactions");
|
||||||
final Collection<LoanTransactionData> currentLoanRepayments = this.loanReadPlatformService.retrieveLoanTransactions(loanId);
|
final Collection<LoanTransactionData> currentLoanRepayments = this.loanReadPlatformService.retrieveLoanTransactions(loanId);
|
||||||
if (!CollectionUtils.isEmpty(currentLoanRepayments)) {
|
if (!CollectionUtils.isEmpty(currentLoanRepayments)) {
|
||||||
loanRepayments = currentLoanRepayments;
|
loanRepayments = currentLoanRepayments;
|
||||||
@@ -226,6 +230,10 @@ public class LoansApiResource {
|
|||||||
|
|
||||||
if (associationParameters.contains("repaymentSchedule") || associationParameters.contains("permissions")) {
|
if (associationParameters.contains("repaymentSchedule") || associationParameters.contains("permissions")) {
|
||||||
|
|
||||||
|
if (associationParameters.contains("repaymentSchedule")) {
|
||||||
|
mandatoryResponseParameters.add("repaymentSchedule");
|
||||||
|
}
|
||||||
|
|
||||||
DisbursementData singleDisbursement = loanBasicDetails.toDisburementData();
|
DisbursementData singleDisbursement = loanBasicDetails.toDisburementData();
|
||||||
repaymentSchedule = this.loanReadPlatformService.retrieveRepaymentSchedule(loanId, loanBasicDetails.getCurrency(),
|
repaymentSchedule = this.loanReadPlatformService.retrieveRepaymentSchedule(loanId, loanBasicDetails.getCurrency(),
|
||||||
singleDisbursement, loanBasicDetails.getTotalDisbursementCharges(), loanBasicDetails.getInArrearsTolerance());
|
singleDisbursement, loanBasicDetails.getTotalDisbursementCharges(), loanBasicDetails.getInArrearsTolerance());
|
||||||
@@ -236,6 +244,7 @@ public class LoansApiResource {
|
|||||||
if (associationParameters.contains("permissions")) {
|
if (associationParameters.contains("permissions")) {
|
||||||
|
|
||||||
if (repaymentSchedule == null) { throw new IllegalStateException(); }
|
if (repaymentSchedule == null) { throw new IllegalStateException(); }
|
||||||
|
mandatoryResponseParameters.add("permissions");
|
||||||
|
|
||||||
// FIXME - KW - Waive feature was changed to waive interest at
|
// FIXME - KW - Waive feature was changed to waive interest at
|
||||||
// anytime so this permission checking is probably not needed -
|
// anytime so this permission checking is probably not needed -
|
||||||
@@ -259,6 +268,7 @@ public class LoansApiResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (associationParameters.contains("charges")) {
|
if (associationParameters.contains("charges")) {
|
||||||
|
mandatoryResponseParameters.add("charges");
|
||||||
charges = this.loanChargeReadPlatformService.retrieveLoanCharges(loanId);
|
charges = this.loanChargeReadPlatformService.retrieveLoanCharges(loanId);
|
||||||
if (CollectionUtils.isEmpty(charges)) {
|
if (CollectionUtils.isEmpty(charges)) {
|
||||||
charges = null; // set back to null so doesnt appear in JSON
|
charges = null; // set back to null so doesnt appear in JSON
|
||||||
@@ -302,7 +312,7 @@ public class LoansApiResource {
|
|||||||
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
|
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
|
||||||
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, null, guarantors);
|
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);
|
return this.toApiJsonSerializer.serialize(settings, loanAccount, LOAN_DATA_PARAMETERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-6
@@ -13,13 +13,12 @@ public class DefaultLoanLifecycleStateMachine implements LoanLifecycleStateMachi
|
|||||||
@Override
|
@Override
|
||||||
public LoanStatus transition(LoanEvent loanEvent, LoanStatus from) {
|
public LoanStatus transition(LoanEvent loanEvent, LoanStatus from) {
|
||||||
|
|
||||||
LoanStatus newState = null;
|
LoanStatus newState = from;
|
||||||
|
|
||||||
switch (loanEvent) {
|
switch (loanEvent) {
|
||||||
case LOAN_CREATED:
|
case LOAN_CREATED:
|
||||||
if (from == null) {
|
if (from == null) {
|
||||||
newState = stateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL,
|
newState = stateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL, allowedLoanStatuses);
|
||||||
allowedLoanStatuses);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LOAN_REJECTED:
|
case LOAN_REJECTED:
|
||||||
@@ -65,7 +64,7 @@ public class DefaultLoanLifecycleStateMachine implements LoanLifecycleStateMachi
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WRITE_OFF_OUTSTANDING:
|
case WRITE_OFF_OUTSTANDING:
|
||||||
if (this.anyOfAllowedWhenComingFrom(from,LoanStatus.ACTIVE)) {
|
if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE)) {
|
||||||
newState = stateOf(LoanStatus.CLOSED_WRITTEN_OFF, allowedLoanStatuses);
|
newState = stateOf(LoanStatus.CLOSED_WRITTEN_OFF, allowedLoanStatuses);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -100,8 +99,7 @@ public class DefaultLoanLifecycleStateMachine implements LoanLifecycleStateMachi
|
|||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean anyOfAllowedWhenComingFrom(final LoanStatus state,
|
private boolean anyOfAllowedWhenComingFrom(final LoanStatus state, final LoanStatus... allowedStates) {
|
||||||
final LoanStatus... allowedStates) {
|
|
||||||
boolean allowed = false;
|
boolean allowed = false;
|
||||||
|
|
||||||
for (LoanStatus allowedState : allowedStates) {
|
for (LoanStatus allowedState : allowedStates) {
|
||||||
|
|||||||
+10
-9
@@ -803,7 +803,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||||
this.loanStatus = statusEnum.getValue();
|
this.loanStatus = statusEnum.getValue();
|
||||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||||
}
|
|
||||||
|
|
||||||
LocalDate rejectedOn = command.localDateValueOfParameterNamed("rejectedOnDate");
|
LocalDate rejectedOn = command.localDateValueOfParameterNamed("rejectedOnDate");
|
||||||
if (rejectedOn == null) {
|
if (rejectedOn == null) {
|
||||||
@@ -830,6 +829,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
final String errorMessage = "The date on which a loan is rejected cannot be in the future.";
|
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);
|
throw new InvalidLoanStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, rejectedOn);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
@@ -843,7 +843,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||||
this.loanStatus = statusEnum.getValue();
|
this.loanStatus = statusEnum.getValue();
|
||||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||||
}
|
|
||||||
|
|
||||||
LocalDate withdrawnOn = command.localDateValueOfParameterNamed("withdrawnOnDate");
|
LocalDate withdrawnOn = command.localDateValueOfParameterNamed("withdrawnOnDate");
|
||||||
if (withdrawnOn == null) {
|
if (withdrawnOn == null) {
|
||||||
@@ -871,6 +870,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
final String errorMessage = "The date on which a loan is withdrawn cannot be in the future.";
|
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);
|
throw new InvalidLoanStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, command);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
@@ -883,17 +883,19 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||||
this.loanStatus = statusEnum.getValue();
|
this.loanStatus = statusEnum.getValue();
|
||||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||||
}
|
|
||||||
|
|
||||||
|
// only do below if status has changed in the 'approval' case
|
||||||
LocalDate approvedOn = command.localDateValueOfParameterNamed("approvedOnDate");
|
LocalDate approvedOn = command.localDateValueOfParameterNamed("approvedOnDate");
|
||||||
|
String approvedOnDateChange = command.stringValueOfParameterNamed("approvedOnDate");
|
||||||
if (approvedOn == null) {
|
if (approvedOn == null) {
|
||||||
approvedOn = command.localDateValueOfParameterNamed("eventDate");
|
approvedOn = command.localDateValueOfParameterNamed("eventDate");
|
||||||
|
approvedOnDateChange = command.stringValueOfParameterNamed("eventDate");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.approvedOnDate = approvedOn.toDate();
|
this.approvedOnDate = approvedOn.toDate();
|
||||||
actualChanges.put("locale", command.locale());
|
actualChanges.put("locale", command.locale());
|
||||||
actualChanges.put("dateFormat", command.dateFormat());
|
actualChanges.put("dateFormat", command.dateFormat());
|
||||||
actualChanges.put("approvedOnDate", command.stringValueOfParameterNamed("approvedOnDate"));
|
actualChanges.put("approvedOnDate", approvedOnDateChange);
|
||||||
|
|
||||||
final LocalDate submittalDate = new LocalDate(this.submittedOnDate);
|
final LocalDate submittalDate = new LocalDate(this.submittedOnDate);
|
||||||
if (approvedOn.isBefore(submittalDate)) {
|
if (approvedOn.isBefore(submittalDate)) {
|
||||||
@@ -912,6 +914,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
this.loanofficer, approvedOn);
|
this.loanofficer, approvedOn);
|
||||||
this.loanOfficerHistory.add(loanOfficerAssignmentHistory);
|
this.loanOfficerHistory.add(loanOfficerAssignmentHistory);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
@@ -925,12 +928,12 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
if (!statusEnum.hasStateOf(currentStatus)) {
|
if (!statusEnum.hasStateOf(currentStatus)) {
|
||||||
this.loanStatus = statusEnum.getValue();
|
this.loanStatus = statusEnum.getValue();
|
||||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||||
}
|
|
||||||
|
|
||||||
this.approvedOnDate = null;
|
this.approvedOnDate = null;
|
||||||
actualChanges.put("approvedOnDate", "");
|
actualChanges.put("approvedOnDate", "");
|
||||||
|
|
||||||
this.loanOfficerHistory.clear();
|
this.loanOfficerHistory.clear();
|
||||||
|
}
|
||||||
|
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
@@ -952,7 +955,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||||
this.loanStatus = statusEnum.getValue();
|
this.loanStatus = statusEnum.getValue();
|
||||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||||
}
|
|
||||||
|
|
||||||
LocalDate disbursedOn = command.localDateValueOfParameterNamed("disbursedOnDate");
|
LocalDate disbursedOn = command.localDateValueOfParameterNamed("disbursedOnDate");
|
||||||
if (disbursedOn == null) {
|
if (disbursedOn == null) {
|
||||||
@@ -975,6 +977,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
if (isRepaymentScheduleRegenerationRequiredForDisbursement(disbursedOn)) {
|
if (isRepaymentScheduleRegenerationRequiredForDisbursement(disbursedOn)) {
|
||||||
regenerateRepaymentSchedule(currency);
|
regenerateRepaymentSchedule(currency);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
@@ -1067,19 +1070,17 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
if (!statusEnum.hasStateOf(currentStatus)) {
|
if (!statusEnum.hasStateOf(currentStatus)) {
|
||||||
this.loanStatus = statusEnum.getValue();
|
this.loanStatus = statusEnum.getValue();
|
||||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||||
}
|
|
||||||
|
|
||||||
this.approvedOnDate = null;
|
this.approvedOnDate = null;
|
||||||
actualChanges.put("disbursedOnDate", "");
|
actualChanges.put("disbursedOnDate", "");
|
||||||
|
|
||||||
updateLoanToPreDisbursalState();
|
updateLoanToPreDisbursalState();
|
||||||
|
}
|
||||||
|
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLoanToPreDisbursalState() {
|
private void updateLoanToPreDisbursalState() {
|
||||||
this.loanStatus = LoanStatus.APPROVED.getValue();
|
|
||||||
|
|
||||||
this.loanTransactions.clear();
|
this.loanTransactions.clear();
|
||||||
this.disbursedOnDate = null;
|
this.disbursedOnDate = null;
|
||||||
|
|
||||||
|
|||||||
-1
@@ -3,5 +3,4 @@ package org.mifosplatform.portfolio.loanaccount.domain;
|
|||||||
public interface LoanLifecycleStateMachine {
|
public interface LoanLifecycleStateMachine {
|
||||||
|
|
||||||
LoanStatus transition(LoanEvent loanEvent, LoanStatus from);
|
LoanStatus transition(LoanEvent loanEvent, LoanStatus from);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -294,6 +294,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
"User has no authority to approve loan with a date in the past."); }
|
"User has no authority to approve loan with a date in the past."); }
|
||||||
|
|
||||||
final Map<String, Object> changes = loan.loanApplicationApproval(command, defaultLoanLifecycleStateMachine());
|
final Map<String, Object> changes = loan.loanApplicationApproval(command, defaultLoanLifecycleStateMachine());
|
||||||
|
if (!changes.isEmpty()) {
|
||||||
this.loanRepository.save(loan);
|
this.loanRepository.save(loan);
|
||||||
|
|
||||||
final String noteText = command.stringValueOfParameterNamed("note");
|
final String noteText = command.stringValueOfParameterNamed("note");
|
||||||
@@ -302,6 +303,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
changes.put("note", noteText);
|
changes.put("note", noteText);
|
||||||
this.noteRepository.save(note);
|
this.noteRepository.save(note);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
@@ -323,6 +325,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
final Loan loan = retrieveLoanBy(loanId);
|
final Loan loan = retrieveLoanBy(loanId);
|
||||||
|
|
||||||
final Map<String, Object> changes = loan.undoApproval(defaultLoanLifecycleStateMachine());
|
final Map<String, Object> changes = loan.undoApproval(defaultLoanLifecycleStateMachine());
|
||||||
|
if (!changes.isEmpty()) {
|
||||||
this.loanRepository.save(loan);
|
this.loanRepository.save(loan);
|
||||||
|
|
||||||
String noteText = command.stringValueOfParameterNamed("note");
|
String noteText = command.stringValueOfParameterNamed("note");
|
||||||
@@ -330,6 +333,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
Note note = Note.loanNote(loan, noteText);
|
Note note = Note.loanNote(loan, noteText);
|
||||||
this.noteRepository.save(note);
|
this.noteRepository.save(note);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
@@ -359,6 +363,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
"User has no authority to reject loan with a date in the past."); }
|
"User has no authority to reject loan with a date in the past."); }
|
||||||
|
|
||||||
final Map<String, Object> changes = loan.loanApplicationRejection(command, defaultLoanLifecycleStateMachine());
|
final Map<String, Object> changes = loan.loanApplicationRejection(command, defaultLoanLifecycleStateMachine());
|
||||||
|
if (!changes.isEmpty()) {
|
||||||
this.loanRepository.save(loan);
|
this.loanRepository.save(loan);
|
||||||
|
|
||||||
String noteText = command.stringValueOfParameterNamed("note");
|
String noteText = command.stringValueOfParameterNamed("note");
|
||||||
@@ -366,6 +371,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
Note note = Note.loanNote(loan, noteText);
|
Note note = Note.loanNote(loan, noteText);
|
||||||
this.noteRepository.save(note);
|
this.noteRepository.save(note);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
@@ -395,6 +401,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
"User has no authority to mark loan as withdrawn by applicant with a date in the past."); }
|
"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());
|
final Map<String, Object> changes = loan.loanApplicationWithdrawnByApplicant(command, defaultLoanLifecycleStateMachine());
|
||||||
|
if (!changes.isEmpty()) {
|
||||||
this.loanRepository.save(loan);
|
this.loanRepository.save(loan);
|
||||||
|
|
||||||
String noteText = command.stringValueOfParameterNamed("note");
|
String noteText = command.stringValueOfParameterNamed("note");
|
||||||
@@ -402,6 +409,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
Note note = Note.loanNote(loan, noteText);
|
Note note = Note.loanNote(loan, noteText);
|
||||||
this.noteRepository.save(note);
|
this.noteRepository.save(note);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
|
|||||||
+5
-1
@@ -121,9 +121,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final ApplicationCurrency currency = this.applicationCurrencyRepository.findOneByCode(loan.getPrincpal().getCurrencyCode());
|
final ApplicationCurrency currency = this.applicationCurrencyRepository.findOneByCode(loan.getPrincpal().getCurrencyCode());
|
||||||
|
|
||||||
final Map<String, Object> changes = loan.disburse(command, defaultLoanLifecycleStateMachine(), currency);
|
final Map<String, Object> changes = loan.disburse(command, defaultLoanLifecycleStateMachine(), currency);
|
||||||
|
if (!changes.isEmpty()) {
|
||||||
// variable stores Id's of all existing loan transactions (newly created
|
// variable stores Id's of all existing loan transactions (newly created
|
||||||
// loan transactions would not have an Id before save)
|
// loan transactions would not have an Id before save)
|
||||||
Set<Long> existingLoanTransactionIds = new HashSet<Long>();
|
final Set<Long> existingLoanTransactionIds = new HashSet<Long>();
|
||||||
for(LoanTransaction loanTransaction:loan.getLoanTransactions()){
|
for(LoanTransaction loanTransaction:loan.getLoanTransactions()){
|
||||||
if(!(loanTransaction.getId()==null)){
|
if(!(loanTransaction.getId()==null)){
|
||||||
existingLoanTransactionIds.add(loanTransaction.getId());
|
existingLoanTransactionIds.add(loanTransaction.getId());
|
||||||
@@ -151,6 +152,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
LoanDTO loanDTO = populateLoanDTO(loan, newLoanTransactions);
|
LoanDTO loanDTO = populateLoanDTO(loan, newLoanTransactions);
|
||||||
journalEntryWritePlatformService.createJournalEntriesForLoan(loanDTO);
|
journalEntryWritePlatformService.createJournalEntriesForLoan(loanDTO);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
@@ -172,6 +174,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final Loan loan = retrieveLoanBy(loanId);
|
final Loan loan = retrieveLoanBy(loanId);
|
||||||
|
|
||||||
final Map<String, Object> changes = loan.undoDisbursal(defaultLoanLifecycleStateMachine());
|
final Map<String, Object> changes = loan.undoDisbursal(defaultLoanLifecycleStateMachine());
|
||||||
|
if (!changes.isEmpty()) {
|
||||||
this.loanRepository.save(loan);
|
this.loanRepository.save(loan);
|
||||||
|
|
||||||
final String noteText = command.stringValueOfParameterNamed("note");
|
final String noteText = command.stringValueOfParameterNamed("note");
|
||||||
@@ -179,6 +182,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
Note note = Note.loanNote(loan, noteText);
|
Note note = Note.loanNote(loan, noteText);
|
||||||
this.noteRepository.save(note);
|
this.noteRepository.save(note);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
|
|||||||
+1
-1
@@ -74,7 +74,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
|||||||
final InterestMethod interestMethod = InterestMethod.fromInt(command.integerValueOfParameterNamed("interestType"));
|
final InterestMethod interestMethod = InterestMethod.fromInt(command.integerValueOfParameterNamed("interestType"));
|
||||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command
|
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command
|
||||||
.integerValueOfParameterNamed("interestCalculationPeriodType"));
|
.integerValueOfParameterNamed("interestCalculationPeriodType"));
|
||||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.integerValueOfParameterNamed("interestType"));
|
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.integerValueOfParameterNamed("amortizationType"));
|
||||||
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command
|
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command
|
||||||
.integerValueOfParameterNamed("repaymentFrequencyType"));
|
.integerValueOfParameterNamed("repaymentFrequencyType"));
|
||||||
final PeriodFrequencyType interestFrequencyType = PeriodFrequencyType.fromInt(command
|
final PeriodFrequencyType interestFrequencyType = PeriodFrequencyType.fromInt(command
|
||||||
|
|||||||
Reference in New Issue
Block a user