update api-docs and loan functionality from api.
This commit is contained in:
+178
-164
@@ -327,7 +327,7 @@ function getBaseURL(docURL)
|
||||
<div class="tocMatrix">
|
||||
<table class=matrixHeading>
|
||||
<tr class="matrixHeadingBG"><td colspan=2 valign="top"><div class="matrixHeadingVerbs"><table><tr><td>RESOURCES</td></tr></table></div></td><td><table><tr><td><div class="matrixHeadingVerbs">POST</div></td></tr><tr><td><div class=matrixHeadingCommands>create/complex update</div></td></tr></table></td><td><table><tr><td><div class="matrixHeadingVerbs">GET</div></td></tr><tr><td><div class=matrixHeadingCommands>read</div></td></tr></table></td><td><table><tr><td><div class="matrixHeadingVerbs">PUT</div></td></tr><tr><td><div class=matrixHeadingCommands>update</div></td></tr></table></td><td><table><tr><td><div class="matrixHeadingVerbs">DELETE</div></td></tr><tr><td><div class=matrixHeadingCommands>delete</div></td></tr></table></td></tr>
|
||||
<tr><td><a href="#authentication">AUTHENTICATION</a></td><td>authentication</td><td><a href="#authentication_permissions">Verify Authentication</a></td><td></td><td></td><td></td></tr>
|
||||
<tr><td><a href="#authentication">AUTHENTICATION</a></td><td>authentication</td><td><a href="#authenticate_request">Verify Authentication</a></td><td></td><td></td><td></td></tr>
|
||||
<tr class="alt"><td><a href="#users">USER</a></td><td>users</td><td><a href="#users_create">Create a User</a></td><td><a href="#users_list">List Users</a></td><td></td><td></td></tr>
|
||||
<tr><td></td><td>users/{userId}</td><td></td><td><a href="#users_retrieve">Retrieve a User</a></td><td><a href="#users_update">Update a User</a></td><td><a href="#users_delete">Delete a User</a></td></tr>
|
||||
<tr class="alt"><td><a href="#roles">ROLE</a></td><td>roles</td><td><a href="#roles_create">Create a New Role</a></td><td><a href="#roles_list">List Roles</a></td><td></td><td></td></tr>
|
||||
@@ -634,9 +634,6 @@ var jqxhr = $.ajax({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- start of clients api docs -->
|
||||
<a id="clients" name="clients" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
@@ -673,26 +670,37 @@ var jqxhr = $.ajax({
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/clients</code>
|
||||
<code class="method-response">[ {
|
||||
"id" : 14,
|
||||
"accountNo": "14",
|
||||
"firstname" : "Patrick",
|
||||
"middlename" : "J"
|
||||
"lastname" : "Asare-Frimpong",
|
||||
"displayName" : "Patrick J Asare-Frimpong",
|
||||
"officeId" : 2,
|
||||
"officeName" : "sub branch 1",
|
||||
"externalId" : "123AB",
|
||||
"joinedDate" : [ 2012, 4, 18 ]
|
||||
}, {
|
||||
"id" : 13,
|
||||
"accountNo": "0000000AB5",
|
||||
"fullname" : "My micro business Ltd."
|
||||
"displayName" : "My micro business Ltd.",
|
||||
"officeId" : 5,
|
||||
"officeName" : "Majmoua",
|
||||
"joinedDate" : [ 2011, 12, 1 ]
|
||||
}... ]
|
||||
<code class="method-response">[
|
||||
{
|
||||
"id": 2,
|
||||
"accountNo": "000000002",
|
||||
"externalId": "one/78",
|
||||
"fullname": "New Business to Create",
|
||||
"displayName": "New Business to Create",
|
||||
"officeId": 1,
|
||||
"officeName": "Head Office",
|
||||
"joinedDate": [
|
||||
2006,
|
||||
6,
|
||||
13
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"accountNo": "000000001",
|
||||
"externalId": "786YYH7",
|
||||
"firstname": "Petra",
|
||||
"lastname": "Yton",
|
||||
"displayName": "Petra Yton",
|
||||
"officeId": 1,
|
||||
"officeName": "Head Office",
|
||||
"joinedDate": [
|
||||
2009,
|
||||
3,
|
||||
4
|
||||
]
|
||||
}
|
||||
]
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
@@ -713,23 +721,15 @@ var jqxhr = $.ajax({
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/clients/template</code>
|
||||
<code class="method-response">{
|
||||
"joinedDate" : [ 2012, 5, 29 ],
|
||||
"allowedOffices" : [ {
|
||||
"officeId": 1,
|
||||
"joinedDate": [ 2013, 2, 5],
|
||||
"allowedOffices": [
|
||||
{
|
||||
"id": 1,
|
||||
"name" : "Demo MFI Head Office"
|
||||
}, {
|
||||
"id" : 2,
|
||||
"name" : "sub branch 1"
|
||||
}, {
|
||||
"id" : 8,
|
||||
"name" : "moi aussi"
|
||||
}, {
|
||||
"id" : 3,
|
||||
"name" : "sub branch 2"
|
||||
}, {
|
||||
"id" : 4,
|
||||
"name" : "sub branch 3"
|
||||
} ]
|
||||
"name": "Head Office",
|
||||
"nameDecorated": "Head Office"
|
||||
}
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -751,12 +751,18 @@ var jqxhr = $.ajax({
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/clients/{clientId}</code>
|
||||
<code class="method-response">{
|
||||
"id": 1,
|
||||
"firstname" : "Patrick",
|
||||
"lastname" : "O'Meara",
|
||||
"displayName" : "Patrick O'Meara",
|
||||
"accountNo": "000000001",
|
||||
"externalId": "786YYH7",
|
||||
"firstname": "Petra",
|
||||
"lastname": "Yton",
|
||||
"displayName": "Petra Yton",
|
||||
"officeId": 1,
|
||||
"officeName" : "Demo MFI Head Office",
|
||||
"joinedDate" : [ 2009, 1, 4 ]
|
||||
"officeName": "Head Office",
|
||||
"joinedDate": [
|
||||
2009,
|
||||
3,
|
||||
4
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -792,8 +798,8 @@ Request Body:
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"officeId": 1,
|
||||
"clientId": 83,
|
||||
"resourceId": 83
|
||||
"clientId": 1,
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -812,8 +818,8 @@ Request Body:
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"officeId": 1,
|
||||
"clientId": 84,
|
||||
"resourceId": 84
|
||||
"clientId": 2,
|
||||
"resourceId": 2
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -826,7 +832,7 @@ Request Body:
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">PUT https://Domain Name/api/v1/clients/{clientId}</code>
|
||||
<code class="method-request">PUT clients/83
|
||||
<code class="method-request">PUT clients/1
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
@@ -838,8 +844,8 @@ Request Body:
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"officeId": 1,
|
||||
"clientId": 83,
|
||||
"resourceId": 83,
|
||||
"clientId": 1,
|
||||
"resourceId": 1,
|
||||
"changes": {
|
||||
"externalId": "786444UUUYYH7",
|
||||
"joinedDate": "09 June 2006",
|
||||
@@ -1389,30 +1395,29 @@ Request Body:
|
||||
<br><br>
|
||||
<div class=apiClick>loans/1?associations=all</div>
|
||||
<br><br>
|
||||
<div class=apiClick>loans/1?fields=id,principal,annualInterestRate&associations=summary,repaymentSchedule</div>
|
||||
<div class=apiClick>loans/1?fields=id,principal,annualInterestRate&associations=repaymentSchedule,transactions</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/loans/{loanId}</code>
|
||||
<code class="method-response">{
|
||||
{
|
||||
"id": 1,
|
||||
"accountNo": "000000001",
|
||||
"clientId": 1,
|
||||
"clientName": "Willie O'Meara",
|
||||
"clientName": "Petra Yton",
|
||||
"loanProductId": 1,
|
||||
"loanProductName": "Agricultural Loan",
|
||||
"loanProductDescription": "An agricultural loan given to farmers to help buy crop, stock and machinery. With an arrears tolerance setting of 1,000 CFA, loans are not marked as 'in arrears' or 'in bad standing' if the amount outstanding is less than this. Interest rate is described using monthly percentage rate (MPR) even though the loan typically lasts a year and requires one repayment (typically at time when farmer sells crop)",
|
||||
"loanProductName": "A new loan product for me",
|
||||
"status": {
|
||||
"id": 100,
|
||||
"code": "loanStatusType.submitted.and.pending.approval",
|
||||
"value": "Submitted and pending approval"
|
||||
},
|
||||
"currency": {
|
||||
"code": "XOF",
|
||||
"name": "CFA Franc BCEAO",
|
||||
"decimalPlaces": 0,
|
||||
"displaySymbol": "CFA",
|
||||
"nameCode": "currency.XOF",
|
||||
"displayLabel": "CFA Franc BCEAO (CFA)"
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"displaySymbol": "$",
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"principal": 100000,
|
||||
"termFrequency": 12,
|
||||
@@ -1509,7 +1514,10 @@ Request Body:
|
||||
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 42
|
||||
"officeId": 1,
|
||||
"clientId": 1,
|
||||
"loanId": 1,
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -1542,13 +1550,28 @@ Request Body:
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"locale": "en",
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"eventDate": "07 May 2012",
|
||||
"eventDate": "20 September 2011",
|
||||
"note": "and event note is added"
|
||||
} </code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"resourceId": 37
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"officeId": 1,
|
||||
"clientId": 1,
|
||||
"loanId": 2,
|
||||
"resourceId": 2,
|
||||
"changes": {
|
||||
"status": {
|
||||
"id": 200,
|
||||
"code": "loanStatusType.approved",
|
||||
"value": "Approved"
|
||||
},
|
||||
"locale": "en",
|
||||
"dateFormat": "dd MMMM yyyy",
|
||||
"approvedOnDate": "20 September 2011",
|
||||
"note": "and event note is added"
|
||||
}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -1568,6 +1591,9 @@ Content-Type: application/json
|
||||
No Request Body:
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"officeId": 1,
|
||||
"clientId": 1,
|
||||
"loanId": 1,
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
@@ -1749,27 +1775,20 @@ Request Body:
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/offices</code>
|
||||
<code class="method-response">[ {
|
||||
<code class="method-response">[
|
||||
{
|
||||
"id": 1,
|
||||
"name" : "Demo MFI Head Office",
|
||||
"name": "Head Office",
|
||||
"nameDecorated": "Head Office",
|
||||
"externalId": "1",
|
||||
"openingDate" : [ 2009, 1, 1 ],
|
||||
"openingDate": [
|
||||
2009,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"hierarchy": "."
|
||||
}, {
|
||||
"id" : 2,
|
||||
"name" : "B1",
|
||||
"openingDate" : [ 2012, 4, 1 ],
|
||||
"hierarchy" : ".2.",
|
||||
"parentName" : "Demo MFI Head Office",
|
||||
"parentId" : 1
|
||||
}, {
|
||||
"id" : 3,
|
||||
"name" : "B2",
|
||||
"openingDate" : [ 2012, 4, 4 ],
|
||||
"hierarchy" : ".3.",
|
||||
"parentName" : "Demo MFI Head Office",
|
||||
"parentId" : 1
|
||||
} ]
|
||||
}
|
||||
]
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1790,17 +1809,14 @@ Request Body:
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/offices/template</code>
|
||||
<code class="method-response">{
|
||||
"openingDate" : [ 2012, 5, 28 ],
|
||||
"allowedParents" : [ {
|
||||
"openingDate": [2013,2,4],
|
||||
"allowedParents": [
|
||||
{
|
||||
"id": 1,
|
||||
"name" : "Demo MFI Head Office"
|
||||
}, {
|
||||
"id" : 2,
|
||||
"name" : "B1"
|
||||
}, {
|
||||
"id" : 3,
|
||||
"name" : "B2"
|
||||
} ]
|
||||
"name": "Head Office",
|
||||
"nameDecorated": "Head Office"
|
||||
}
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -1821,7 +1837,8 @@ Request Body:
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/offices/1</code>
|
||||
<code class="method-response">{
|
||||
"id": 1,
|
||||
"name" : "Demo MFI Head Office",
|
||||
"name": "Head Office",
|
||||
"nameDecorated": "Head Office",
|
||||
"externalId": "1",
|
||||
"openingDate": [2009,1,1],
|
||||
"hierarchy": "."
|
||||
@@ -1876,8 +1893,8 @@ Request Body:
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"officeId": 3,
|
||||
"resourceId": 3,
|
||||
"officeId": 1,
|
||||
"resourceId": 1,
|
||||
"changes": {
|
||||
"name": "Name is updated"
|
||||
}
|
||||
@@ -1994,9 +2011,9 @@ Request Body:
|
||||
},
|
||||
"annualInterestRate": 21,
|
||||
"amortizationType": {
|
||||
"id": 0,
|
||||
"code": "amortizationType.equal.principal",
|
||||
"value": "Equal principle payments"
|
||||
"id": 1,
|
||||
"code": "amortizationType.equal.installments",
|
||||
"value": "Equal installments"
|
||||
},
|
||||
"interestType": {
|
||||
"id": 0,
|
||||
@@ -2243,9 +2260,9 @@ Request Body:
|
||||
},
|
||||
"annualInterestRate": 21,
|
||||
"amortizationType": {
|
||||
"id": 0,
|
||||
"code": "amortizationType.equal.principal",
|
||||
"value": "Equal principle payments"
|
||||
"id": 1,
|
||||
"code": "amortizationType.equal.installments",
|
||||
"value": "Equal installments"
|
||||
},
|
||||
"interestType": {
|
||||
"id": 0,
|
||||
@@ -2354,14 +2371,39 @@ Request Body:
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/currencies</code>
|
||||
<code class="method-response">{
|
||||
"selectedCurrencyOptions" : [ {
|
||||
"selectedCurrencyOptions": [
|
||||
{
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"displaySymbol": "$",
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
}]
|
||||
}
|
||||
],
|
||||
"currencyOptions": [
|
||||
{
|
||||
"code": "AFN",
|
||||
"name": "Afghanistan Afghani",
|
||||
"decimalPlaces": 2,
|
||||
"nameCode": "currency.AFN",
|
||||
"displayLabel": "Afghanistan Afghani [AFN]"
|
||||
},
|
||||
{
|
||||
"code": "ALL",
|
||||
"name": "Albanian Lek",
|
||||
"decimalPlaces": 2,
|
||||
"nameCode": "currency.ALL",
|
||||
"displayLabel": "Albanian Lek [ALL]"
|
||||
},
|
||||
{
|
||||
"code": "ZWD",
|
||||
"name": "Zimbabwe Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"nameCode": "currency.ZWD",
|
||||
"displayLabel": "Zimbabwe Dollar [ZWD]"
|
||||
}
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -2474,7 +2516,7 @@ Request Body:
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2
|
||||
"resourceId": 4
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -2498,8 +2540,12 @@ Request Body:
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "MyNewCode",
|
||||
"systemDefined": false
|
||||
"name": "Gender",
|
||||
"systemDefined": true
|
||||
},{
|
||||
"id": 3,
|
||||
"name": "Education",
|
||||
"systemDefined": true
|
||||
}
|
||||
]
|
||||
</code>
|
||||
@@ -2532,8 +2578,8 @@ Request Body:
|
||||
<p>Updates the details of a code if it is not system defined.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">PUT https://Domain Name/api/v1/codes/2</code>
|
||||
<code class="method-request">PUT codes/2
|
||||
<code class="method-declaration">PUT https://Domain Name/api/v1/codes/4</code>
|
||||
<code class="method-request">PUT codes/4
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
@@ -2541,7 +2587,7 @@ Request Body:
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2,
|
||||
"resourceId": 4,
|
||||
"changes": {
|
||||
"name": "MyNewCode(changed)"
|
||||
}
|
||||
@@ -2557,12 +2603,12 @@ Request Body:
|
||||
<p>Deletes a code if it is not system defined.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">DELETE https://Domain Name/api/v1/codes/2</code>
|
||||
<code class="method-request">DELETE codes/2
|
||||
<code class="method-declaration">DELETE https://Domain Name/api/v1/codes/4</code>
|
||||
<code class="method-request">DELETE codes/4
|
||||
Content-Type: application/json
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2
|
||||
"resourceId": 4
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -2803,7 +2849,7 @@ Request Body:
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -2821,38 +2867,8 @@ Request Body:
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/charges</code>
|
||||
<code class="method-response">[
|
||||
{
|
||||
"id": 2,
|
||||
"id": 1,
|
||||
"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,
|
||||
"penalty": false,
|
||||
"currency": {
|
||||
@@ -2863,7 +2879,7 @@ Request Body:
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"amount": 456,
|
||||
"amount": 230.560000,
|
||||
"chargeTimeType": {
|
||||
"id": 1,
|
||||
"code": "chargeTimeType.disbursement",
|
||||
@@ -2891,14 +2907,14 @@ Request Body:
|
||||
<h4>Retrieve a Charge</h4>
|
||||
<p>Returns the details of a defined Charge.</p>
|
||||
<p>Example Requests: </p>
|
||||
<div class=apiClick>charges/2</div>
|
||||
<div class=apiClick>charges/1</div>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/charges/2</code>
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/charges/1</code>
|
||||
<code class="method-response">{
|
||||
"id": 2,
|
||||
"id": 1,
|
||||
"name": "Loan service fee",
|
||||
"active": false,
|
||||
"active": true,
|
||||
"penalty": false,
|
||||
"currency": {
|
||||
"code": "USD",
|
||||
@@ -2908,7 +2924,7 @@ Request Body:
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"amount": 230.56,
|
||||
"amount": 230.560000,
|
||||
"chargeTimeType": {
|
||||
"id": 1,
|
||||
"code": "chargeTimeType.disbursement",
|
||||
@@ -2945,7 +2961,7 @@ Request Body:
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2,
|
||||
"resourceId": 1,
|
||||
"changes": {
|
||||
"name": "Loan service fee(changed)"
|
||||
}
|
||||
@@ -2961,12 +2977,12 @@ Request Body:
|
||||
<p>Deletes a Charge.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">DELETE https://Domain Name/api/v1/charges/2</code>
|
||||
<code class="method-request">DELETE charges/2
|
||||
<code class="method-declaration">DELETE https://Domain Name/api/v1/charges/1</code>
|
||||
<code class="method-request">DELETE charges/1
|
||||
Content-Type: application/json
|
||||
</code>
|
||||
<code class="method-response">{
|
||||
"resourceId": 2
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
@@ -3540,7 +3556,7 @@ Request Body:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="authentication_permissions" name="authentication_permissions" class="old-syle-anchor"> </a>
|
||||
<a id="authenticate_request" name="authenticate_request" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Verify authentication</h4>
|
||||
@@ -3562,9 +3578,7 @@ No Request Body
|
||||
]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/authentication?username={username}&password={password}</code>
|
||||
|
||||
<code class="method-request">POST authentication?username=mifos&password=fail
|
||||
Content-Type: application/json
|
||||
No Request Body
|
||||
@@ -4143,7 +4157,7 @@ Request body:
|
||||
<tr><td></td><td>datatables/{datatable}/{apptableId}/{datatableId}</td><td></td><td><a href="#datatables_update_1M">Update Entry in Data Table (One to Many)</a></td><td></td><td><a href="#datatables_delete_1M">Delete Entry in Data Table (One to Many)</a></td></tr>
|
||||
<tr class="alt"><td><a href="#reports">REPORT</a></td><td>reports</td><td></td><td><a href="#reports_list">List Reports</a></td><td></td><td></td></tr>
|
||||
<tr><td></td><td>reports/{reportName}</td><td></td><td><a href="#report_run">Run a Report</a></td><td></td><td></td></tr>
|
||||
<tr class="alt"><td><a href="#authentication">AUTHENTICATION</a></td><td>authentication</td><td><a href="#authentication_permissions">Verify Authentication</a></td><td></td><td></td><td></td></tr>
|
||||
<tr class="alt"><td><a href="#authentication">AUTHENTICATION</a></td><td>authentication</td><td><a href="#authenticate_request">Verify Authentication</a></td><td></td><td></td><td></td></tr>
|
||||
<tr><td><a href="#users">USER</a></td><td>users</td><td><a href="#users_create">Create a User</a></td><td><a href="#users_list">List Users</a></td><td></td><td></td></tr>
|
||||
<tr class="alt"><td></td><td>users/{userId}</td><td></td><td><a href="#users_retrieve">Retrieve a User</a></td><td><a href="#users_update">Update a User</a></td><td><a href="#users_delete">Delete a User</a></td></tr>
|
||||
<tr><td><a href="#roles">ROLE</a></td><td>roles</td><td><a href="#roles_create">Create a New Role</a></td><td><a href="#roles_list">List Roles</a></td><td></td><td></td></tr>
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
DROP TABLE IF EXISTS `additional client fields data`;
|
||||
DROP TABLE IF EXISTS `extra family details data`;
|
||||
DROP TABLE IF EXISTS `additional loan fields data`;
|
||||
|
||||
CREATE TABLE `additional client fields data` (
|
||||
`client_id` bigint(20) NOT NULL,
|
||||
`Business Description` varchar(100) DEFAULT NULL,
|
||||
`Years in Business` int(11) DEFAULT NULL,
|
||||
`Gender_cd` int(11) DEFAULT NULL,
|
||||
`Education_cv` varchar(60) DEFAULT NULL,
|
||||
`Next Visit` date DEFAULT NULL,
|
||||
`Highest Rate Paid` decimal(19,6) DEFAULT NULL,
|
||||
`Comment` text,
|
||||
PRIMARY KEY (`client_id`),
|
||||
CONSTRAINT `FK_Additional Client Fields Data_1` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `extra family details data` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`client_id` bigint(20) NOT NULL,
|
||||
`Name` varchar(40) DEFAULT NULL,
|
||||
`Date of Birth` date DEFAULT NULL,
|
||||
`Points Score` int(11) DEFAULT NULL,
|
||||
`Education_cdHighest` int(11) DEFAULT NULL,
|
||||
`Other Notes` text,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `FK_Extra Family Details Data_1` (`client_id`),
|
||||
CONSTRAINT `FK_Extra Family Details Data_1` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `additional loan fields data` (
|
||||
`loan_id` bigint(20) NOT NULL,
|
||||
`Business Description` varchar(100) DEFAULT NULL,
|
||||
`Years in Business` int(11) DEFAULT NULL,
|
||||
`Gender_cd` int(11) DEFAULT NULL,
|
||||
`Education_cv` varchar(60) DEFAULT NULL,
|
||||
`Next Visit` date DEFAULT NULL,
|
||||
`Highest Rate Paid` decimal(19,6) DEFAULT NULL,
|
||||
`Comment` text,
|
||||
PRIMARY KEY (`loan_id`),
|
||||
CONSTRAINT `FK_Additional Loan Fields Data_1` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
@@ -21,6 +21,7 @@ INSERT INTO `mifosplatform-tenants`.`tenants`
|
||||
(`name`, `identifier`,`schema_name`)
|
||||
VALUES
|
||||
('Default Demo Tenant', 'default' ,'mifostenant-default'),
|
||||
('API Docs Demo', 'apidocs' ,'mifostenant-apidocs'),
|
||||
('GK Maarg', 'gk-maarg' ,'mifostenant-gk-maarg'),
|
||||
('Latam Demo', 'latam' ,'mifostenant-latam'),
|
||||
('Bare bones Demo', 'barebones' ,'mifostenant-barebones');
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,15 @@
|
||||
default Demo
|
||||
======
|
||||
|
||||
This demo database contains:
|
||||
|
||||
- DDL of latest schema
|
||||
|
||||
- Minimum reference data required for deployment of platform which is:
|
||||
- Its mandatory to have one selected currency so we default to several of latin-america currencies
|
||||
- Its mandatory to have one root or head office, so we have one created by default called a 'Latam HO'
|
||||
- Permissions supported/needed by latest release of software are setup
|
||||
- Its mandatory to have at least one role when creating new users so we have one role created by default called 'Super user' which has the special permission 'Full Authorisation'. Any user with this role can do anything in the system.
|
||||
- Its required to have at least one application user setup so remaining setup can be done through ui so we have on application user created by default with username 'quipo' with a password of 'quipo'. Application users must be associated with an office and a role so this user is associated with 'Latam HO' and 'Super user' role allowing this user to do any operation in any office(branch).
|
||||
|
||||
Minimum amount of data to support api-docs interaction.
|
||||
+96
-290
File diff suppressed because one or more lines are too long
+52
@@ -0,0 +1,52 @@
|
||||
-- add code and code values for datatables dropdowns
|
||||
INSERT INTO `m_code` (`id`, `code_name`, `is_system_defined`) VALUES (2, 'Gender', 1);
|
||||
INSERT INTO `m_code` (`id`, `code_name`, `is_system_defined`) VALUES (3, 'Education', 1);
|
||||
|
||||
INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (2, 'Male', 1);
|
||||
INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (2, 'Female', 2);
|
||||
|
||||
INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'Primary', 1);
|
||||
INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'Secondary', 2);
|
||||
INSERT INTO `m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'University', 3);
|
||||
|
||||
DROP TABLE IF EXISTS `extra_client_details`;
|
||||
CREATE TABLE `extra_client_details` (
|
||||
`client_id` bigint(20) NOT NULL,
|
||||
`Business Description` varchar(100) DEFAULT NULL,
|
||||
`Years in Business` int(11) DEFAULT NULL,
|
||||
`Gender_cd` int(11) DEFAULT NULL,
|
||||
`Education_cv` varchar(60) DEFAULT NULL,
|
||||
`Next Visit` date DEFAULT NULL,
|
||||
`Highest Rate Paid` decimal(19,6) DEFAULT NULL,
|
||||
`Comment` text,
|
||||
PRIMARY KEY (`client_id`),
|
||||
CONSTRAINT `FK_latam_extra_client_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
DROP TABLE IF EXISTS `extra_family_details`;
|
||||
CREATE TABLE `extra_family_details` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`client_id` bigint(20) NOT NULL,
|
||||
`Name` varchar(40) DEFAULT NULL,
|
||||
`Date of Birth` date DEFAULT NULL,
|
||||
`Points Score` int(11) DEFAULT NULL,
|
||||
`Education_cd_Highest` int(11) DEFAULT NULL,
|
||||
`Other Notes` text,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `FK_Extra Family Details Data_1` (`client_id`),
|
||||
CONSTRAINT `FK_latam_family_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
DROP TABLE IF EXISTS `extra_loan_details`;
|
||||
CREATE TABLE `extra_loan_details` (
|
||||
`loan_id` bigint(20) NOT NULL,
|
||||
`Business Description` varchar(100) DEFAULT NULL,
|
||||
`Years in Business` int(11) DEFAULT NULL,
|
||||
`Gender_cd` int(11) DEFAULT NULL,
|
||||
`Education_cv` varchar(60) DEFAULT NULL,
|
||||
`Next Visit` date DEFAULT NULL,
|
||||
`Highest Rate Paid` decimal(19,6) DEFAULT NULL,
|
||||
`Comment` text,
|
||||
PRIMARY KEY (`loan_id`),
|
||||
CONSTRAINT `FK_latam_extra_loan_details` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
@@ -0,0 +1,49 @@
|
||||
DROP TABLE IF EXISTS `latam_extra_client_details`;
|
||||
CREATE TABLE `latam_extra_client_details` (
|
||||
`client_id` bigint(20) NOT NULL,
|
||||
`Business Description` varchar(100) DEFAULT NULL,
|
||||
`Years in Business` int(11) DEFAULT NULL,
|
||||
`Gender_cd` int(11) DEFAULT NULL,
|
||||
`Education_cv` varchar(60) DEFAULT NULL,
|
||||
`Next Visit` date DEFAULT NULL,
|
||||
`Highest Rate Paid` decimal(19,6) DEFAULT NULL,
|
||||
`Comment` text,
|
||||
PRIMARY KEY (`client_id`),
|
||||
CONSTRAINT `FK_latam_extra_client_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
DROP TABLE IF EXISTS `latam_family_details`;
|
||||
CREATE TABLE `latam_family_details` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`client_id` bigint(20) NOT NULL,
|
||||
`Name` varchar(40) DEFAULT NULL,
|
||||
`Date of Birth` date DEFAULT NULL,
|
||||
`Points Score` int(11) DEFAULT NULL,
|
||||
`Education_cd_Highest` int(11) DEFAULT NULL,
|
||||
`Other Notes` text,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `FK_Extra Family Details Data_1` (`client_id`),
|
||||
CONSTRAINT `FK_latam_family_details` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
DROP TABLE IF EXISTS `latam_extra_loan_details`;
|
||||
CREATE TABLE `latam_extra_loan_details` (
|
||||
`loan_id` bigint(20) NOT NULL,
|
||||
`Business Description` varchar(100) DEFAULT NULL,
|
||||
`Years in Business` int(11) DEFAULT NULL,
|
||||
`Gender_cd` int(11) DEFAULT NULL,
|
||||
`Education_cv` varchar(60) DEFAULT NULL,
|
||||
`Next Visit` date DEFAULT NULL,
|
||||
`Highest Rate Paid` decimal(19,6) DEFAULT NULL,
|
||||
`Comment` text,
|
||||
PRIMARY KEY (`loan_id`),
|
||||
CONSTRAINT `FK_latam_extra_loan_details` FOREIGN KEY (`loan_id`) REFERENCES `m_loan` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
INSERT INTO `mifostenant-latam`.`m_code` (`code_name`, `is_system_defined`) VALUES ('Gender', 1);
|
||||
INSERT INTO `mifostenant-latam`.`m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (2, 'Male', 1); INSERT INTO `mifostenant-latam`.`m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (2, 'Female', 2);
|
||||
|
||||
|
||||
INSERT INTO `mifostenant-latam`.`m_code` (`code_name`, `is_system_defined`) VALUES ('Education', 1);
|
||||
INSERT INTO `mifostenant-latam`.`m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'Primary', 1); INSERT INTO `mifostenant-latam`.`m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'Secondary', 2); INSERT INTO `mifostenant-latam`.`m_code_value` (`code_id`, `code_value`, `order_position`) VALUES (3, 'University', 3);
|
||||
+21
-3
@@ -9,8 +9,8 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Used to process the query parameters provided in a API request to see features of
|
||||
* the RESTful API are being asked for such as:
|
||||
* Used to process the query parameters provided in a API request to see
|
||||
* features of the RESTful API are being asked for such as:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>Pretty printing through pretty=true, defaults to false</li>
|
||||
@@ -21,6 +21,23 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class ApiRequestParameterHelper {
|
||||
|
||||
public ApiRequestJsonSerializationSettings process(final MultivaluedMap<String, String> queryParameters,
|
||||
final Set<String> mandatoryResponseParameters) {
|
||||
|
||||
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(queryParameters);
|
||||
if (!responseParameters.isEmpty()) {
|
||||
responseParameters.addAll(mandatoryResponseParameters);
|
||||
}
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(queryParameters);
|
||||
final boolean template = ApiParameterHelper.template(queryParameters);
|
||||
final Long commandId = ApiParameterHelper.commandId(queryParameters);
|
||||
final boolean makerCheckerable = ApiParameterHelper.makerCheckerable(queryParameters);
|
||||
final boolean includeJson = ApiParameterHelper.includeJson(queryParameters);
|
||||
|
||||
return ApiRequestJsonSerializationSettings
|
||||
.from(prettyPrint, responseParameters, template, commandId, makerCheckerable, includeJson);
|
||||
}
|
||||
|
||||
public ApiRequestJsonSerializationSettings process(final MultivaluedMap<String, String> queryParameters) {
|
||||
|
||||
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(queryParameters);
|
||||
@@ -30,6 +47,7 @@ public class ApiRequestParameterHelper {
|
||||
final boolean makerCheckerable = ApiParameterHelper.makerCheckerable(queryParameters);
|
||||
final boolean includeJson = ApiParameterHelper.includeJson(queryParameters);
|
||||
|
||||
return ApiRequestJsonSerializationSettings.from(prettyPrint, responseParameters, template, commandId, makerCheckerable, includeJson);
|
||||
return ApiRequestJsonSerializationSettings
|
||||
.from(prettyPrint, responseParameters, template, commandId, makerCheckerable, includeJson);
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -25,8 +25,9 @@ public class CreateDatatableEntryCommandHandler implements NewCommandSourceHandl
|
||||
|
||||
this.writePlatformService.newDatatableEntry(command.entityName(), command.getApptableId(), command);
|
||||
|
||||
// FIXME - kw - need to find office and either group/client/loan that
|
||||
// this datatable is against.
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(command.getApptableId()).build();
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(command.getApptableId()) //
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+152
-334
@@ -37,19 +37,15 @@ import org.springframework.stereotype.Service;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Service
|
||||
public class ReadWriteNonCoreDataServiceImpl implements
|
||||
ReadWriteNonCoreDataService {
|
||||
public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataService {
|
||||
|
||||
private final static Logger logger = LoggerFactory
|
||||
.getLogger(ReadWriteNonCoreDataServiceImpl.class);
|
||||
private final static Logger logger = LoggerFactory.getLogger(ReadWriteNonCoreDataServiceImpl.class);
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final FromJsonHelper fromJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public ReadWriteNonCoreDataServiceImpl(
|
||||
final PlatformSecurityContext context,
|
||||
final FromJsonHelper fromJsonHelper) {
|
||||
public ReadWriteNonCoreDataServiceImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper) {
|
||||
this.context = context;
|
||||
this.fromJsonHelper = fromJsonHelper;
|
||||
}
|
||||
@@ -67,36 +63,24 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
andClause = " and application_table_name = '" + appTable + "'";
|
||||
}
|
||||
// PERMITTED datatables
|
||||
String sql = "select application_table_name, registered_table_name"
|
||||
+ " from x_registered_table "
|
||||
+ " where exists"
|
||||
+ " (select 'f'"
|
||||
+ " 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()
|
||||
String sql = "select application_table_name, registered_table_name" + " from x_registered_table " + " where exists"
|
||||
+ " (select 'f'" + " 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))) "
|
||||
+ andClause
|
||||
+ " order by application_table_name, registered_table_name";
|
||||
+ andClause + " order by application_table_name, registered_table_name";
|
||||
|
||||
String sqlErrorMsg = "Application Table Name: " + appTable + " sql: "
|
||||
+ sql;
|
||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql,
|
||||
sqlErrorMsg);
|
||||
String sqlErrorMsg = "Application Table Name: " + appTable + " sql: " + sql;
|
||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql, sqlErrorMsg);
|
||||
|
||||
List<DatatableData> datatables = new ArrayList<DatatableData>();
|
||||
try {
|
||||
while (rs.next()) {
|
||||
datatables.add(new DatatableData(rs
|
||||
.getString("application_table_name"), rs
|
||||
.getString("registered_table_name")));
|
||||
datatables.add(new DatatableData(rs.getString("application_table_name"), rs.getString("registered_table_name")));
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
||||
e.getMessage(), sqlErrorMsg);
|
||||
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg);
|
||||
}
|
||||
|
||||
return datatables;
|
||||
@@ -115,49 +99,21 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
String deletePermission = "'DELETE_" + datatable + "'";
|
||||
String deletePermissionChecker = "'DELETE_" + datatable + "_CHECKER'";
|
||||
// TODO - put in batch command later
|
||||
String sql = "insert into x_registered_table (registered_table_name, application_table_name) values ('"
|
||||
+ datatable + "', '" + appTable + "')";
|
||||
String sql = "insert into x_registered_table (registered_table_name, application_table_name) values ('" + datatable + "', '"
|
||||
+ appTable + "')";
|
||||
|
||||
genericDataService.updateSQL(sql, "SQL: " + sql);
|
||||
/*
|
||||
* add all permissions, including checker permissions for maintenance
|
||||
* tasks
|
||||
*/
|
||||
sql = "insert into m_permission (grouping, code, action_name, entity_name, can_maker_checker) values "
|
||||
+ "('datatable', "
|
||||
+ createPermission
|
||||
+ ", 'CREATE', '"
|
||||
+ datatable
|
||||
+ "', true),"
|
||||
+ "('datatable', "
|
||||
+ 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)";
|
||||
sql = "insert into m_permission (grouping, code, action_name, entity_name, can_maker_checker) values " + "('datatable', "
|
||||
+ createPermission + ", 'CREATE', '" + datatable + "', true)," + "('datatable', " + 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);
|
||||
}
|
||||
@@ -166,10 +122,8 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
public void deregisterDatatable(final String datatable) {
|
||||
// TODO - put in batch command later
|
||||
|
||||
String permissionList = "('CREATE_" + datatable + "', 'CREATE_"
|
||||
+ datatable + "_CHECKER', 'READ_" + datatable + "', 'UPDATE_"
|
||||
+ datatable + "', 'UPDATE_" + datatable + "_CHECKER', 'DELETE_"
|
||||
+ datatable + "', 'DELETE_" + datatable + "_CHECKER')";
|
||||
String permissionList = "('CREATE_" + datatable + "', 'CREATE_" + datatable + "_CHECKER', 'READ_" + datatable + "', 'UPDATE_"
|
||||
+ 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 "
|
||||
+ permissionList + ")";
|
||||
@@ -178,59 +132,43 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
sql = "delete from m_permission where code in " + permissionList;
|
||||
genericDataService.updateSQL(sql, "SQL: " + sql);
|
||||
|
||||
sql = "delete from x_registered_table where registered_table_name = '"
|
||||
+ datatable + "'";
|
||||
sql = "delete from x_registered_table where registered_table_name = '" + datatable + "'";
|
||||
genericDataService.updateSQL(sql, "SQL: " + sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newDatatableEntry(final String datatable,
|
||||
final Long appTableId, final JsonCommand command) {
|
||||
String appTable = getWithinScopeApplicationTableName(datatable,
|
||||
appTableId);
|
||||
public void newDatatableEntry(final String datatable, final Long appTableId, final JsonCommand command) {
|
||||
String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
|
||||
|
||||
List<ResultsetColumnHeader> columnHeaders = getDatatableResultsetColumnHeaders(datatable);
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {
|
||||
}.getType();
|
||||
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(
|
||||
typeOfMap, command.json());
|
||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
|
||||
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
|
||||
|
||||
String sql = getAddSql(columnHeaders, datatable, getFKField(appTable),
|
||||
appTableId, dataParams);
|
||||
String sql = getAddSql(columnHeaders, datatable, getFKField(appTable), appTableId, dataParams);
|
||||
|
||||
genericDataService.updateSQL(sql, "SQL: " + sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> updateDatatableEntryOneToOne(
|
||||
final String datatable, final Long appTableId,
|
||||
final JsonCommand command) {
|
||||
public Map<String, Object> updateDatatableEntryOneToOne(final String datatable, final Long appTableId, final JsonCommand command) {
|
||||
|
||||
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable,
|
||||
appTableId, null, null);
|
||||
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, null);
|
||||
|
||||
if (grs.getData().size() == 0)
|
||||
throw new DataTableNotFoundException(datatable, appTableId);
|
||||
if (grs.getData().size() == 0) throw new DataTableNotFoundException(datatable, appTableId);
|
||||
|
||||
if (grs.getData().size() > 1)
|
||||
throw new PlatformDataIntegrityException(
|
||||
"error.msg.attempting.multiple.update",
|
||||
"Application Table: " + datatable + " Foreign Key Id: "
|
||||
+ appTableId);
|
||||
throw new PlatformDataIntegrityException("error.msg.attempting.multiple.update", "Application Table: " + datatable
|
||||
+ " Foreign Key Id: " + appTableId);
|
||||
|
||||
String fkName = getFKField(getApplicationTableName(datatable));
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {
|
||||
}.getType();
|
||||
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(
|
||||
typeOfMap, command.json());
|
||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
|
||||
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
|
||||
|
||||
final Map<String, Object> changes = getAffectedAndChangedColumns(grs,
|
||||
dataParams, fkName);
|
||||
final Map<String, Object> changes = getAffectedAndChangedColumns(grs, dataParams, fkName);
|
||||
|
||||
if (changes.size() == 0)
|
||||
return changes;
|
||||
if (changes.size() == 0) return changes;
|
||||
|
||||
String sql = getUpdateSql(datatable, fkName, appTableId, changes);
|
||||
|
||||
@@ -244,26 +182,19 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> updateDatatableEntryOneToMany(
|
||||
final String datatable, final Long appTableId,
|
||||
final Long datatableId, final JsonCommand command) {
|
||||
public Map<String, Object> updateDatatableEntryOneToMany(final String datatable, final Long appTableId, final Long datatableId,
|
||||
final JsonCommand command) {
|
||||
|
||||
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable,
|
||||
appTableId, null, datatableId);
|
||||
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, datatableId);
|
||||
|
||||
if (grs.getData().size() == 0)
|
||||
throw new DataTableNotFoundException(datatable, appTableId);
|
||||
if (grs.getData().size() == 0) throw new DataTableNotFoundException(datatable, appTableId);
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {
|
||||
}.getType();
|
||||
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(
|
||||
typeOfMap, command.json());
|
||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
|
||||
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
|
||||
|
||||
final Map<String, Object> changes = getAffectedAndChangedColumns(grs,
|
||||
dataParams, "id");
|
||||
final Map<String, Object> changes = getAffectedAndChangedColumns(grs, dataParams, "id");
|
||||
|
||||
if (changes.size() == 0)
|
||||
return changes;
|
||||
if (changes.size() == 0) return changes;
|
||||
|
||||
String sql = getUpdateSql(datatable, "id", datatableId, changes);
|
||||
|
||||
@@ -277,21 +208,17 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDatatableEntries(final String datatable,
|
||||
final Long appTableId) {
|
||||
public void deleteDatatableEntries(final String datatable, final Long appTableId) {
|
||||
|
||||
String appTable = getWithinScopeApplicationTableName(datatable,
|
||||
appTableId);
|
||||
String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
|
||||
|
||||
String sql = getDeleteEntriesSql(datatable, getFKField(appTable),
|
||||
appTableId);
|
||||
String sql = getDeleteEntriesSql(datatable, getFKField(appTable), appTableId);
|
||||
|
||||
genericDataService.updateSQL(sql, "SQL: " + sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDatatableEntry(final String datatable,
|
||||
final Long appTableId, final Long datatableId) {
|
||||
public void deleteDatatableEntry(final String datatable, final Long appTableId, final Long datatableId) {
|
||||
|
||||
getWithinScopeApplicationTableName(datatable, appTableId);
|
||||
|
||||
@@ -301,12 +228,10 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericResultsetData retrieveDataTableGenericResultSet(
|
||||
final String datatable, final Long appTableId, final String order,
|
||||
public GenericResultsetData retrieveDataTableGenericResultSet(final String datatable, final Long appTableId, final String order,
|
||||
final Long id) {
|
||||
|
||||
String appTable = getWithinScopeApplicationTableName(datatable,
|
||||
appTableId);
|
||||
String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
|
||||
|
||||
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
|
||||
// (when updating)
|
||||
if (id == null) {
|
||||
sql = sql + "select * from `" + datatable + "` where "
|
||||
+ getFKField(appTable) + " = " + appTableId;
|
||||
sql = sql + "select * from `" + datatable + "` where " + getFKField(appTable) + " = " + appTableId;
|
||||
} else {
|
||||
sql = sql + "select * from `" + datatable + "` where id = " + id;
|
||||
}
|
||||
|
||||
if (order != null)
|
||||
sql = sql + " order by " + order;
|
||||
if (order != null) sql = sql + " order by " + order;
|
||||
|
||||
List<ResultsetDataRow> result = fillDatatableResultSetDataRows(sql);
|
||||
|
||||
return new GenericResultsetData(columnHeaders, result);
|
||||
}
|
||||
|
||||
private void checkMainResourceExistsWithinScope(final String appTable,
|
||||
final Long appTableId) {
|
||||
private void checkMainResourceExistsWithinScope(final String appTable, final Long appTableId) {
|
||||
|
||||
String unscopedSql = "select t.id from `" + appTable
|
||||
+ "` t ${dataScopeCriteria} where t.id = " + appTableId;
|
||||
String unscopedSql = "select t.id from `" + appTable + "` t ${dataScopeCriteria} where t.id = " + appTableId;
|
||||
|
||||
String sql = dataScopedSQL(unscopedSql, appTable);
|
||||
|
||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : "
|
||||
+ sql);
|
||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql);
|
||||
|
||||
if (rs.size() == 0)
|
||||
throw new DataTableNotFoundException(appTable, appTableId);
|
||||
if (rs.size() == 0) throw new DataTableNotFoundException(appTable, appTableId);
|
||||
}
|
||||
|
||||
private String dataScopedSQL(final String unscopedSQL, final String appTable) {
|
||||
@@ -356,45 +275,33 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
if (appTable.equalsIgnoreCase("m_client")) {
|
||||
dataScopeCriteria = " join m_office o on o.id = t.office_id and o.hierarchy like '"
|
||||
+ currentUser.getOffice().getHierarchy() + "%'";
|
||||
dataScopeCriteria = " join m_office o on o.id = t.office_id and o.hierarchy like '" + currentUser.getOffice().getHierarchy()
|
||||
+ "%'";
|
||||
}
|
||||
if (appTable.equalsIgnoreCase("m_loan")) {
|
||||
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 '"
|
||||
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 '"
|
||||
+ currentUser.getOffice().getHierarchy() + "%'";
|
||||
}
|
||||
|
||||
if (dataScopeCriteria == null) {
|
||||
throw new PlatformDataIntegrityException(
|
||||
"error.msg.invalid.dataScopeCriteria",
|
||||
"Application Table: " + appTable
|
||||
+ " not catered for in data Scoping");
|
||||
}
|
||||
if (dataScopeCriteria == null) { throw new PlatformDataIntegrityException("error.msg.invalid.dataScopeCriteria",
|
||||
"Application Table: " + appTable + " not catered for in data Scoping"); }
|
||||
|
||||
return genericDataService.replace(unscopedSQL, "${dataScopeCriteria}",
|
||||
dataScopeCriteria);
|
||||
return genericDataService.replace(unscopedSQL, "${dataScopeCriteria}", dataScopeCriteria);
|
||||
|
||||
}
|
||||
|
||||
private void validateAppTable(final String appTable) {
|
||||
|
||||
if (appTable.equalsIgnoreCase("m_client"))
|
||||
return;
|
||||
if (appTable.equalsIgnoreCase("m_loan"))
|
||||
return;
|
||||
if (appTable.equalsIgnoreCase("m_client")) return;
|
||||
if (appTable.equalsIgnoreCase("m_loan")) return;
|
||||
|
||||
throw new PlatformDataIntegrityException(
|
||||
"error.msg.invalid.application.table",
|
||||
"Invalid Application Table: " + appTable);
|
||||
throw new PlatformDataIntegrityException("error.msg.invalid.application.table", "Invalid Application Table: " + appTable);
|
||||
}
|
||||
|
||||
private List<ResultsetDataRow> fillDatatableResultSetDataRows(
|
||||
final String sql) {
|
||||
private List<ResultsetDataRow> fillDatatableResultSetDataRows(final String sql) {
|
||||
|
||||
String sqlErrorMsg = "Sql: " + sql;
|
||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql,
|
||||
sqlErrorMsg);
|
||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql, sqlErrorMsg);
|
||||
|
||||
List<ResultsetDataRow> resultsetDataRows = new ArrayList<ResultsetDataRow>();
|
||||
|
||||
@@ -420,21 +327,16 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
|
||||
return resultsetDataRows;
|
||||
} catch (SQLException e) {
|
||||
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
||||
e.getMessage(), sqlErrorMsg);
|
||||
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
private String getWithinScopeApplicationTableName(final String datatable,
|
||||
final Long appTableId) {
|
||||
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '"
|
||||
+ datatable + "'";
|
||||
private String getWithinScopeApplicationTableName(final String datatable, final Long appTableId) {
|
||||
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'";
|
||||
|
||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : "
|
||||
+ sql);
|
||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql);
|
||||
|
||||
if (rs.size() == 0)
|
||||
throw new DataTableNotFoundException(datatable);
|
||||
if (rs.size() == 0) throw new DataTableNotFoundException(datatable);
|
||||
|
||||
try {
|
||||
rs.next();
|
||||
@@ -444,29 +346,24 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
|
||||
return appTable;
|
||||
} catch (SQLException e) {
|
||||
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
||||
e.getMessage());
|
||||
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String getApplicationTableName(final String datatable) {
|
||||
// TODO - only used for update... can probably remove this after as its
|
||||
// a reread
|
||||
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 : "
|
||||
+ sql);
|
||||
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql);
|
||||
|
||||
if (rs.size() == 0)
|
||||
throw new DataTableNotFoundException(datatable);
|
||||
if (rs.size() == 0) throw new DataTableNotFoundException(datatable);
|
||||
|
||||
try {
|
||||
rs.next();
|
||||
return rs.getString("application_table_name");
|
||||
} catch (SQLException e) {
|
||||
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
||||
e.getMessage());
|
||||
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,21 +375,17 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
private CachedRowSet getDatatableMetaData(final String datatable) {
|
||||
|
||||
String sql = "select COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMN_KEY"
|
||||
+ " from INFORMATION_SCHEMA.COLUMNS "
|
||||
+ " where TABLE_SCHEMA = schema() and TABLE_NAME = '"
|
||||
+ datatable + "'order by ORDINAL_POSITION";
|
||||
+ " from INFORMATION_SCHEMA.COLUMNS " + " where TABLE_SCHEMA = schema() and TABLE_NAME = '" + datatable
|
||||
+ "'order by ORDINAL_POSITION";
|
||||
|
||||
CachedRowSet columnDefinitions = genericDataService.getCachedResultSet(
|
||||
sql, "SQL: " + sql);
|
||||
CachedRowSet columnDefinitions = genericDataService.getCachedResultSet(sql, "SQL: " + sql);
|
||||
|
||||
if (columnDefinitions.size() > 0)
|
||||
return columnDefinitions;
|
||||
if (columnDefinitions.size() > 0) return columnDefinitions;
|
||||
|
||||
throw new DataTableNotFoundException(datatable);
|
||||
}
|
||||
|
||||
private List<ResultsetColumnHeader> getDatatableResultsetColumnHeaders(
|
||||
final String datatable) {
|
||||
private List<ResultsetColumnHeader> getDatatableResultsetColumnHeaders(final String datatable) {
|
||||
|
||||
CachedRowSet columnDefinitions = getDatatableMetaData(datatable);
|
||||
|
||||
@@ -517,20 +410,15 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
else
|
||||
rsch.setColumnPrimaryKey(false);
|
||||
|
||||
Long columnLength = columnDefinitions
|
||||
.getLong("CHARACTER_MAXIMUM_LENGTH");
|
||||
if (columnLength > 0)
|
||||
rsch.setColumnLength(columnDefinitions
|
||||
.getLong("CHARACTER_MAXIMUM_LENGTH"));
|
||||
Long columnLength = columnDefinitions.getLong("CHARACTER_MAXIMUM_LENGTH");
|
||||
if (columnLength > 0) rsch.setColumnLength(columnDefinitions.getLong("CHARACTER_MAXIMUM_LENGTH"));
|
||||
|
||||
rsch.setColumnType(columnDefinitions.getString("DATA_TYPE"));
|
||||
|
||||
/* look for codes */
|
||||
if (rsch.getColumnType().equalsIgnoreCase("varchar"))
|
||||
addCodesValueIfNecessary(rsch, "_cv");
|
||||
if (rsch.getColumnType().equalsIgnoreCase("varchar")) addCodesValueIfNecessary(rsch, "_cv");
|
||||
|
||||
if (rsch.getColumnType().equalsIgnoreCase("int"))
|
||||
addCodesValueIfNecessary(rsch, "_cd");
|
||||
if (rsch.getColumnType().equalsIgnoreCase("int")) addCodesValueIfNecessary(rsch, "_cd");
|
||||
|
||||
rsch.setColumnDisplayType();
|
||||
|
||||
@@ -540,46 +428,36 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
return columnHeaders;
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
||||
e.getMessage());
|
||||
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addCodesValueIfNecessary(final ResultsetColumnHeader rsch,
|
||||
final String code_suffix) {
|
||||
private void addCodesValueIfNecessary(final ResultsetColumnHeader rsch, final String code_suffix) {
|
||||
int codePosition = rsch.getColumnName().indexOf(code_suffix);
|
||||
if (codePosition > 0) {
|
||||
String codeName = rsch.getColumnName().substring(0, codePosition);
|
||||
|
||||
String sql = "select v.id, v.code_value from m_code m "
|
||||
+ " join m_code_value v on v.code_id = m.id "
|
||||
+ " where m.code_name = '" + codeName
|
||||
+ "' order by v.order_position, v.id";
|
||||
String sql = "select v.id, v.code_value from m_code m " + " join m_code_value v on v.code_id = m.id "
|
||||
+ " where m.code_name = '" + codeName + "' order by v.order_position, v.id";
|
||||
|
||||
CachedRowSet rsValues = genericDataService.getCachedResultSet(sql,
|
||||
"SQL: " + sql);
|
||||
CachedRowSet rsValues = genericDataService.getCachedResultSet(sql, "SQL: " + sql);
|
||||
|
||||
try {
|
||||
while (rsValues.next()) {
|
||||
rsch.getColumnValues().add(
|
||||
new ResultsetColumnValue(rsValues.getInt("id"),
|
||||
rsValues.getString("code_value")));
|
||||
rsch.getColumnValues().add(new ResultsetColumnValue(rsValues.getInt("id"), rsValues.getString("code_value")));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new PlatformDataIntegrityException("error.msg.sql.error",
|
||||
e.getMessage());
|
||||
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getAddSql(final List<ResultsetColumnHeader> columnHeaders,
|
||||
final String datatable, final String fkName, final Long appTableId,
|
||||
final Map<String, String> queryParams) {
|
||||
private String getAddSql(final List<ResultsetColumnHeader> columnHeaders, final String datatable, final String fkName,
|
||||
final Long appTableId, final Map<String, String> queryParams) {
|
||||
|
||||
final Map<String, String> affectedColumns = getAffectedColumns(
|
||||
columnHeaders, queryParams, fkName);
|
||||
final Map<String, String> affectedColumns = getAffectedColumns(columnHeaders, queryParams, fkName);
|
||||
|
||||
String pValueWrite = "";
|
||||
String addSql = "";
|
||||
@@ -595,24 +473,20 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
if (StringUtils.isEmpty(pValue)) {
|
||||
pValueWrite = "null";
|
||||
} else {
|
||||
pValueWrite = singleQuote
|
||||
+ genericDataService.replace(pValue, singleQuote,
|
||||
singleQuote + singleQuote) + singleQuote;
|
||||
pValueWrite = singleQuote + genericDataService.replace(pValue, singleQuote, singleQuote + singleQuote) + singleQuote;
|
||||
}
|
||||
columnName = "`" + key + "`";
|
||||
insertColumns += ", " + columnName;
|
||||
selectColumns += "," + pValueWrite + " as " + columnName;
|
||||
}
|
||||
|
||||
addSql = "insert into `" + datatable + "` (`" + fkName + "` "
|
||||
+ insertColumns + ")" + " select " + appTableId + " as id"
|
||||
addSql = "insert into `" + datatable + "` (`" + fkName + "` " + insertColumns + ")" + " select " + appTableId + " as id"
|
||||
+ selectColumns;
|
||||
|
||||
return addSql;
|
||||
}
|
||||
|
||||
private String getUpdateSql(final String datatable,
|
||||
final String keyFieldName, final Long keyFieldValue,
|
||||
private String getUpdateSql(final String datatable, final String keyFieldName, final Long keyFieldValue,
|
||||
final Map<String, Object> changedColumns) {
|
||||
|
||||
// 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
|
||||
// data
|
||||
|
||||
if (changedColumns.size() == 0)
|
||||
return null;
|
||||
if (changedColumns.size() == 0) return null;
|
||||
|
||||
String pValue = null;
|
||||
String pValueWrite = "";
|
||||
@@ -643,9 +516,7 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
if (StringUtils.isEmpty(pValue)) {
|
||||
pValueWrite = "null";
|
||||
} else {
|
||||
pValueWrite = singleQuote
|
||||
+ genericDataService.replace(pValue, singleQuote,
|
||||
singleQuote + singleQuote) + singleQuote;
|
||||
pValueWrite = singleQuote + genericDataService.replace(pValue, singleQuote, singleQuote + singleQuote) + singleQuote;
|
||||
}
|
||||
sql += "`" + key + "` = " + pValueWrite;
|
||||
}
|
||||
@@ -655,12 +526,10 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
return sql;
|
||||
}
|
||||
|
||||
private Map<String, Object> getAffectedAndChangedColumns(
|
||||
final GenericResultsetData grs,
|
||||
final Map<String, String> queryParams, final String fkName) {
|
||||
private Map<String, Object> getAffectedAndChangedColumns(final GenericResultsetData grs, final Map<String, String> queryParams,
|
||||
final String fkName) {
|
||||
|
||||
Map<String, String> affectedColumns = getAffectedColumns(
|
||||
grs.getColumnHeaders(), queryParams, fkName);
|
||||
Map<String, String> affectedColumns = getAffectedColumns(grs.getColumnHeaders(), queryParams, fkName);
|
||||
Map<String, Object> affectedAndChangedColumns = new HashMap<String, Object>();
|
||||
String columnValue;
|
||||
|
||||
@@ -674,8 +543,7 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
return affectedAndChangedColumns;
|
||||
}
|
||||
|
||||
private boolean columnChanged(final String key, final String keyValue,
|
||||
final GenericResultsetData grs) {
|
||||
private boolean columnChanged(final String key, final String keyValue, final GenericResultsetData grs) {
|
||||
|
||||
List<String> columnValues = grs.getData().get(0).getRow();
|
||||
|
||||
@@ -696,20 +564,16 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
}
|
||||
}
|
||||
|
||||
throw new PlatformDataIntegrityException(
|
||||
"error.msg.invalid.columnName", "Parameter Column Name: " + key
|
||||
+ " not found");
|
||||
throw new PlatformDataIntegrityException("error.msg.invalid.columnName", "Parameter Column Name: " + key + " not found");
|
||||
}
|
||||
|
||||
private Map<String, String> getAffectedColumns(
|
||||
final List<ResultsetColumnHeader> columnHeaders,
|
||||
final Map<String, String> queryParams, final String keyFieldName) {
|
||||
private Map<String, String> getAffectedColumns(final List<ResultsetColumnHeader> columnHeaders, final Map<String, String> queryParams,
|
||||
final String keyFieldName) {
|
||||
|
||||
String dateFormat = queryParams.get("dateFormat");
|
||||
Locale clientApplicationLocale = null;
|
||||
String localeQueryParam = queryParams.get("locale");
|
||||
if (!(StringUtils.isBlank(localeQueryParam)))
|
||||
clientApplicationLocale = new Locale(queryParams.get("locale"));
|
||||
if (!(StringUtils.isBlank(localeQueryParam))) clientApplicationLocale = new Locale(queryParams.get("locale"));
|
||||
|
||||
String underscore = "_";
|
||||
String space = " ";
|
||||
@@ -724,134 +588,95 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
// ignores id and foreign key fields
|
||||
// also ignores locale and dateformat fields that are used for
|
||||
// validating numeric and date data
|
||||
if (!((key.equalsIgnoreCase("id"))
|
||||
|| (key.equalsIgnoreCase(keyFieldName))
|
||||
|| (key.equals("locale")) || (key.equals("dateFormat")))) {
|
||||
if (!((key.equalsIgnoreCase("id")) || (key.equalsIgnoreCase(keyFieldName)) || (key.equals("locale")) || (key
|
||||
.equals("dateFormat")))) {
|
||||
notFound = true;
|
||||
// matches incoming fields with and without underscores (spaces
|
||||
// and underscores considered the same)
|
||||
queryParamColumnUnderscored = genericDataService.replace(key,
|
||||
space, underscore);
|
||||
queryParamColumnUnderscored = genericDataService.replace(key, space, underscore);
|
||||
for (ResultsetColumnHeader columnHeader : columnHeaders) {
|
||||
if (notFound) {
|
||||
columnHeaderUnderscored = genericDataService
|
||||
.replace(columnHeader.getColumnName(), space,
|
||||
underscore);
|
||||
if (queryParamColumnUnderscored
|
||||
.equalsIgnoreCase(columnHeaderUnderscored)) {
|
||||
columnHeaderUnderscored = genericDataService.replace(columnHeader.getColumnName(), space, underscore);
|
||||
if (queryParamColumnUnderscored.equalsIgnoreCase(columnHeaderUnderscored)) {
|
||||
pValue = queryParams.get(key);
|
||||
pValue = validateColumn(columnHeader, pValue,
|
||||
dateFormat, clientApplicationLocale);
|
||||
affectedColumns.put(columnHeader.getColumnName(),
|
||||
pValue);
|
||||
pValue = validateColumn(columnHeader, pValue, dateFormat, clientApplicationLocale);
|
||||
affectedColumns.put(columnHeader.getColumnName(), pValue);
|
||||
notFound = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (notFound) {
|
||||
throw new PlatformDataIntegrityException(
|
||||
"error.msg.column.not.found", "Column: " + key
|
||||
+ " Not Found");
|
||||
}
|
||||
if (notFound) { throw new PlatformDataIntegrityException("error.msg.column.not.found", "Column: " + key + " Not Found"); }
|
||||
}
|
||||
}
|
||||
return affectedColumns;
|
||||
}
|
||||
|
||||
private String validateColumn(final ResultsetColumnHeader columnHeader,
|
||||
final String pValue, final String dateFormat,
|
||||
private String validateColumn(final ResultsetColumnHeader columnHeader, final String pValue, final String dateFormat,
|
||||
final Locale clientApplicationLocale) {
|
||||
|
||||
String paramValue = pValue;
|
||||
if ((columnHeader.getColumnDisplayType().equals("DATE"))
|
||||
|| (columnHeader.getColumnDisplayType().equals("INTEGER"))
|
||||
|| (columnHeader.getColumnDisplayType().equals("DECIMAL")))
|
||||
paramValue = paramValue.trim();
|
||||
if ((columnHeader.getColumnDisplayType().equals("DATE")) || (columnHeader.getColumnDisplayType().equals("INTEGER"))
|
||||
|| (columnHeader.getColumnDisplayType().equals("DECIMAL"))) paramValue = paramValue.trim();
|
||||
|
||||
if ((StringUtils.isEmpty(paramValue))
|
||||
&& (!(columnHeader.isColumnNullable()))) {
|
||||
if ((StringUtils.isEmpty(paramValue)) && (!(columnHeader.isColumnNullable()))) {
|
||||
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
ApiParameterError error = ApiParameterError.parameterError(
|
||||
"error.msg.column.mandatory", "Mandatory",
|
||||
ApiParameterError error = ApiParameterError.parameterError("error.msg.column.mandatory", "Mandatory",
|
||||
columnHeader.getColumnName());
|
||||
dataValidationErrors.add(error);
|
||||
throw new PlatformApiDataValidationException(
|
||||
"validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors);
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||
dataValidationErrors);
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(paramValue)) {
|
||||
|
||||
if (columnHeader.getColumnValues().size() > 0) {
|
||||
// match code value or id
|
||||
List<ResultsetColumnValue> allowedValues = columnHeader
|
||||
.getColumnValues();
|
||||
List<ResultsetColumnValue> allowedValues = columnHeader.getColumnValues();
|
||||
if (columnHeader.getColumnDisplayType().equals("CODEVALUE")) {
|
||||
for (ResultsetColumnValue allowedValue : allowedValues) {
|
||||
if (paramValue
|
||||
.equalsIgnoreCase(allowedValue.getValue()))
|
||||
return paramValue;
|
||||
if (paramValue.equalsIgnoreCase(allowedValue.getValue())) return paramValue;
|
||||
}
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
ApiParameterError error = ApiParameterError.parameterError(
|
||||
"error.msg.invalid.columnValue",
|
||||
"Value not found in Allowed Value list",
|
||||
columnHeader.getColumnName(), paramValue);
|
||||
ApiParameterError error = ApiParameterError.parameterError("error.msg.invalid.columnValue",
|
||||
"Value not found in Allowed Value list", columnHeader.getColumnName(), paramValue);
|
||||
dataValidationErrors.add(error);
|
||||
throw new PlatformApiDataValidationException(
|
||||
"validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors);
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||
dataValidationErrors);
|
||||
}
|
||||
|
||||
if (columnHeader.getColumnDisplayType().equals("CODELOOKUP")) {
|
||||
for (ResultsetColumnValue allowedValue : allowedValues) {
|
||||
if (paramValue.equals(Integer.toString(allowedValue
|
||||
.getId())))
|
||||
return paramValue;
|
||||
if (paramValue.equals(Integer.toString(allowedValue.getId()))) return paramValue;
|
||||
}
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
ApiParameterError error = ApiParameterError.parameterError(
|
||||
"error.msg.invalid.columnValue",
|
||||
"Value not found in Allowed Value list",
|
||||
columnHeader.getColumnName(), paramValue);
|
||||
ApiParameterError error = ApiParameterError.parameterError("error.msg.invalid.columnValue",
|
||||
"Value not found in Allowed Value list", columnHeader.getColumnName(), paramValue);
|
||||
dataValidationErrors.add(error);
|
||||
throw new PlatformApiDataValidationException(
|
||||
"validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors);
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||
dataValidationErrors);
|
||||
}
|
||||
|
||||
throw new PlatformDataIntegrityException(
|
||||
"error.msg.invalid.columnType.", "Code: "
|
||||
+ columnHeader.getColumnName()
|
||||
+ " - Invalid Type "
|
||||
+ columnHeader.getColumnType()
|
||||
+ " (neither varchar nor int)");
|
||||
throw new PlatformDataIntegrityException("error.msg.invalid.columnType.", "Code: " + columnHeader.getColumnName()
|
||||
+ " - Invalid Type " + columnHeader.getColumnType() + " (neither varchar nor int)");
|
||||
}
|
||||
|
||||
JsonParserHelper helper = new JsonParserHelper();
|
||||
|
||||
if (columnHeader.getColumnDisplayType().equals("DATE")) {
|
||||
LocalDate tmpDate = helper.convertFrom(paramValue,
|
||||
columnHeader.getColumnName(), dateFormat,
|
||||
clientApplicationLocale);
|
||||
if (tmpDate == null)
|
||||
return null;
|
||||
LocalDate tmpDate = helper.convertFrom(paramValue, columnHeader.getColumnName(), dateFormat, clientApplicationLocale);
|
||||
if (tmpDate == null) return null;
|
||||
return tmpDate.toString();
|
||||
}
|
||||
if (columnHeader.getColumnDisplayType().equals("INTEGER")) {
|
||||
Integer tmpInt = helper.convertToInteger(paramValue,
|
||||
columnHeader.getColumnName(), clientApplicationLocale);
|
||||
if (tmpInt == null)
|
||||
return null;
|
||||
Integer tmpInt = helper.convertToInteger(paramValue, columnHeader.getColumnName(), clientApplicationLocale);
|
||||
if (tmpInt == null) return null;
|
||||
return tmpInt.toString();
|
||||
}
|
||||
if (columnHeader.getColumnDisplayType().equals("DECIMAL")) {
|
||||
BigDecimal tmpDecimal = helper.convertFrom(paramValue,
|
||||
columnHeader.getColumnName(), clientApplicationLocale);
|
||||
if (tmpDecimal == null)
|
||||
return null;
|
||||
BigDecimal tmpDecimal = helper.convertFrom(paramValue, columnHeader.getColumnName(), clientApplicationLocale);
|
||||
if (tmpDecimal == null) return null;
|
||||
return tmpDecimal.toString();
|
||||
}
|
||||
|
||||
@@ -860,33 +685,26 @@ public class ReadWriteNonCoreDataServiceImpl implements
|
||||
return paramValue;
|
||||
}
|
||||
|
||||
private String getDeleteEntriesSql(final String datatable,
|
||||
final String FKField, final Long appTableId) {
|
||||
private String getDeleteEntriesSql(final String datatable, final String FKField, final Long appTableId) {
|
||||
|
||||
return "delete from `" + datatable + "` where `" + FKField + "` = "
|
||||
+ appTableId;
|
||||
return "delete from `" + datatable + "` where `" + FKField + "` = " + appTableId;
|
||||
|
||||
}
|
||||
|
||||
private String getDeleteEntrySql(final String datatable,
|
||||
final Long datatableId) {
|
||||
private String getDeleteEntrySql(final String datatable, final Long datatableId) {
|
||||
|
||||
return "delete from `" + datatable + "` where `id` = " + datatableId;
|
||||
|
||||
}
|
||||
|
||||
private boolean notTheSame(final String currValue, final String pValue) {
|
||||
if (StringUtils.isEmpty(currValue) && StringUtils.isEmpty(pValue))
|
||||
return false;
|
||||
if (StringUtils.isEmpty(currValue) && StringUtils.isEmpty(pValue)) return false;
|
||||
|
||||
if (StringUtils.isEmpty(currValue))
|
||||
return true;
|
||||
if (StringUtils.isEmpty(currValue)) return true;
|
||||
|
||||
if (StringUtils.isEmpty(pValue))
|
||||
return true;
|
||||
if (StringUtils.isEmpty(pValue)) return true;
|
||||
|
||||
if (currValue.equals(pValue))
|
||||
return false;
|
||||
if (currValue.equals(pValue)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+13
-3
@@ -76,10 +76,11 @@ public class LoansApiResource {
|
||||
"annualInterestRate", "repaymentFrequencyType", "interestRateFrequencyType", "amortizationType", "interestType",
|
||||
"interestCalculationPeriodType", "submittedOnDate", "approvedOnDate", "expectedDisbursementDate", "actualDisbursementDate",
|
||||
"expectedFirstRepaymentOnDate", "interestChargedFromDate", "closedOnDate", "expectedMaturityDate", "status",
|
||||
"lifeCycleStatusDate", "repaymentSchedule", "transactions", "permissions", "convenienceData", "charges", "productOptions",
|
||||
"lifeCycleStatusDate", "repaymentSchedule", "transactions", "permissions", "convenienceData", "charges", "guarantor", "productOptions",
|
||||
"amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions", "repaymentFrequencyTypeOptions",
|
||||
"interestRateFrequencyTypeOptions", "fundOptions", "repaymentStrategyOptions", "chargeOptions", "loanOfficerId",
|
||||
"loanOfficerName", "loanOfficerOptions", "chargeTemplate"));
|
||||
"loanOfficerName", "loanOfficerOptions", "chargeTemplate", "transactionProcessingStrategyId",
|
||||
"termFrequency", "termPeriodFrequencyType"));
|
||||
|
||||
private final String resourceNameForPermissions = "LOAN";
|
||||
|
||||
@@ -201,6 +202,7 @@ public class LoansApiResource {
|
||||
Collection<LoanChargeData> charges = null;
|
||||
Collection<GuarantorData> guarantors = null;
|
||||
|
||||
final Set<String> mandatoryResponseParameters = new HashSet<String>();
|
||||
boolean convenienceDataRequired = false;
|
||||
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
if (!associationParameters.isEmpty()) {
|
||||
@@ -211,6 +213,7 @@ public class LoansApiResource {
|
||||
}
|
||||
|
||||
if (associationParameters.contains("guarantor")) {
|
||||
mandatoryResponseParameters.add("guarantor");
|
||||
guarantors = this.guarantorReadPlatformService.retrieveGuarantorsForLoan(loanId);
|
||||
if (CollectionUtils.isEmpty(guarantors)) {
|
||||
guarantors = null; // set back to null so doesn't appear in JSON
|
||||
@@ -218,6 +221,7 @@ public class LoansApiResource {
|
||||
}
|
||||
|
||||
if (associationParameters.contains("transactions")) {
|
||||
mandatoryResponseParameters.add("transactions");
|
||||
final Collection<LoanTransactionData> currentLoanRepayments = this.loanReadPlatformService.retrieveLoanTransactions(loanId);
|
||||
if (!CollectionUtils.isEmpty(currentLoanRepayments)) {
|
||||
loanRepayments = currentLoanRepayments;
|
||||
@@ -226,6 +230,10 @@ public class LoansApiResource {
|
||||
|
||||
if (associationParameters.contains("repaymentSchedule") || associationParameters.contains("permissions")) {
|
||||
|
||||
if (associationParameters.contains("repaymentSchedule")) {
|
||||
mandatoryResponseParameters.add("repaymentSchedule");
|
||||
}
|
||||
|
||||
DisbursementData singleDisbursement = loanBasicDetails.toDisburementData();
|
||||
repaymentSchedule = this.loanReadPlatformService.retrieveRepaymentSchedule(loanId, loanBasicDetails.getCurrency(),
|
||||
singleDisbursement, loanBasicDetails.getTotalDisbursementCharges(), loanBasicDetails.getInArrearsTolerance());
|
||||
@@ -236,6 +244,7 @@ public class LoansApiResource {
|
||||
if (associationParameters.contains("permissions")) {
|
||||
|
||||
if (repaymentSchedule == null) { throw new IllegalStateException(); }
|
||||
mandatoryResponseParameters.add("permissions");
|
||||
|
||||
// FIXME - KW - Waive feature was changed to waive interest at
|
||||
// anytime so this permission checking is probably not needed -
|
||||
@@ -259,6 +268,7 @@ public class LoansApiResource {
|
||||
}
|
||||
|
||||
if (associationParameters.contains("charges")) {
|
||||
mandatoryResponseParameters.add("charges");
|
||||
charges = this.loanChargeReadPlatformService.retrieveLoanCharges(loanId);
|
||||
if (CollectionUtils.isEmpty(charges)) {
|
||||
charges = null; // set back to null so doesnt appear in JSON
|
||||
@@ -302,7 +312,7 @@ public class LoansApiResource {
|
||||
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
|
||||
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, null, guarantors);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters(), mandatoryResponseParameters);
|
||||
return this.toApiJsonSerializer.serialize(settings, loanAccount, LOAN_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
|
||||
+3
-5
@@ -13,13 +13,12 @@ public class DefaultLoanLifecycleStateMachine implements LoanLifecycleStateMachi
|
||||
@Override
|
||||
public LoanStatus transition(LoanEvent loanEvent, LoanStatus from) {
|
||||
|
||||
LoanStatus newState = null;
|
||||
LoanStatus newState = from;
|
||||
|
||||
switch (loanEvent) {
|
||||
case LOAN_CREATED:
|
||||
if (from == null) {
|
||||
newState = stateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL,
|
||||
allowedLoanStatuses);
|
||||
newState = stateOf(LoanStatus.SUBMITED_AND_PENDING_APPROVAL, allowedLoanStatuses);
|
||||
}
|
||||
break;
|
||||
case LOAN_REJECTED:
|
||||
@@ -100,8 +99,7 @@ public class DefaultLoanLifecycleStateMachine implements LoanLifecycleStateMachi
|
||||
return match;
|
||||
}
|
||||
|
||||
private boolean anyOfAllowedWhenComingFrom(final LoanStatus state,
|
||||
final LoanStatus... allowedStates) {
|
||||
private boolean anyOfAllowedWhenComingFrom(final LoanStatus state, final LoanStatus... allowedStates) {
|
||||
boolean allowed = false;
|
||||
|
||||
for (LoanStatus allowedState : allowedStates) {
|
||||
|
||||
+10
-9
@@ -803,7 +803,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
|
||||
LocalDate rejectedOn = command.localDateValueOfParameterNamed("rejectedOnDate");
|
||||
if (rejectedOn == null) {
|
||||
@@ -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.";
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, rejectedOn);
|
||||
}
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
@@ -843,7 +843,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
|
||||
LocalDate withdrawnOn = command.localDateValueOfParameterNamed("withdrawnOnDate");
|
||||
if (withdrawnOn == null) {
|
||||
@@ -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.";
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, command);
|
||||
}
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
@@ -883,17 +883,19 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
|
||||
// only do below if status has changed in the 'approval' case
|
||||
LocalDate approvedOn = command.localDateValueOfParameterNamed("approvedOnDate");
|
||||
String approvedOnDateChange = command.stringValueOfParameterNamed("approvedOnDate");
|
||||
if (approvedOn == null) {
|
||||
approvedOn = command.localDateValueOfParameterNamed("eventDate");
|
||||
approvedOnDateChange = command.stringValueOfParameterNamed("eventDate");
|
||||
}
|
||||
|
||||
this.approvedOnDate = approvedOn.toDate();
|
||||
actualChanges.put("locale", command.locale());
|
||||
actualChanges.put("dateFormat", command.dateFormat());
|
||||
actualChanges.put("approvedOnDate", command.stringValueOfParameterNamed("approvedOnDate"));
|
||||
actualChanges.put("approvedOnDate", approvedOnDateChange);
|
||||
|
||||
final LocalDate submittalDate = new LocalDate(this.submittedOnDate);
|
||||
if (approvedOn.isBefore(submittalDate)) {
|
||||
@@ -912,6 +914,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
this.loanofficer, approvedOn);
|
||||
this.loanOfficerHistory.add(loanOfficerAssignmentHistory);
|
||||
}
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
@@ -925,12 +928,12 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (!statusEnum.hasStateOf(currentStatus)) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
|
||||
this.approvedOnDate = null;
|
||||
actualChanges.put("approvedOnDate", "");
|
||||
|
||||
this.loanOfficerHistory.clear();
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
@@ -952,7 +955,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
|
||||
LocalDate disbursedOn = command.localDateValueOfParameterNamed("disbursedOnDate");
|
||||
if (disbursedOn == null) {
|
||||
@@ -975,6 +977,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (isRepaymentScheduleRegenerationRequiredForDisbursement(disbursedOn)) {
|
||||
regenerateRepaymentSchedule(currency);
|
||||
}
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
@@ -1067,19 +1070,17 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (!statusEnum.hasStateOf(currentStatus)) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
|
||||
this.approvedOnDate = null;
|
||||
actualChanges.put("disbursedOnDate", "");
|
||||
|
||||
updateLoanToPreDisbursalState();
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
private void updateLoanToPreDisbursalState() {
|
||||
this.loanStatus = LoanStatus.APPROVED.getValue();
|
||||
|
||||
this.loanTransactions.clear();
|
||||
this.disbursedOnDate = null;
|
||||
|
||||
|
||||
-1
@@ -3,5 +3,4 @@ package org.mifosplatform.portfolio.loanaccount.domain;
|
||||
public interface LoanLifecycleStateMachine {
|
||||
|
||||
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."); }
|
||||
|
||||
final Map<String, Object> changes = loan.loanApplicationApproval(command, defaultLoanLifecycleStateMachine());
|
||||
if (!changes.isEmpty()) {
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
@@ -302,6 +303,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
changes.put("note", noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
@@ -323,6 +325,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
final Map<String, Object> changes = loan.undoApproval(defaultLoanLifecycleStateMachine());
|
||||
if (!changes.isEmpty()) {
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
@@ -330,6 +333,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.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."); }
|
||||
|
||||
final Map<String, Object> changes = loan.loanApplicationRejection(command, defaultLoanLifecycleStateMachine());
|
||||
if (!changes.isEmpty()) {
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
@@ -366,6 +371,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.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."); }
|
||||
|
||||
final Map<String, Object> changes = loan.loanApplicationWithdrawnByApplicant(command, defaultLoanLifecycleStateMachine());
|
||||
if (!changes.isEmpty()) {
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
@@ -402,6 +409,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
|
||||
+5
-1
@@ -121,9 +121,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final ApplicationCurrency currency = this.applicationCurrencyRepository.findOneByCode(loan.getPrincpal().getCurrencyCode());
|
||||
|
||||
final Map<String, Object> changes = loan.disburse(command, defaultLoanLifecycleStateMachine(), currency);
|
||||
if (!changes.isEmpty()) {
|
||||
// variable stores Id's of all existing loan transactions (newly created
|
||||
// loan transactions would not have an Id before save)
|
||||
Set<Long> existingLoanTransactionIds = new HashSet<Long>();
|
||||
final Set<Long> existingLoanTransactionIds = new HashSet<Long>();
|
||||
for(LoanTransaction loanTransaction:loan.getLoanTransactions()){
|
||||
if(!(loanTransaction.getId()==null)){
|
||||
existingLoanTransactionIds.add(loanTransaction.getId());
|
||||
@@ -151,6 +152,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
LoanDTO loanDTO = populateLoanDTO(loan, newLoanTransactions);
|
||||
journalEntryWritePlatformService.createJournalEntriesForLoan(loanDTO);
|
||||
}
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
@@ -172,6 +174,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
final Map<String, Object> changes = loan.undoDisbursal(defaultLoanLifecycleStateMachine());
|
||||
if (!changes.isEmpty()) {
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
@@ -179,6 +182,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
final InterestMethod interestMethod = InterestMethod.fromInt(command.integerValueOfParameterNamed("interestType"));
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command
|
||||
.integerValueOfParameterNamed("interestCalculationPeriodType"));
|
||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.integerValueOfParameterNamed("interestType"));
|
||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.integerValueOfParameterNamed("amortizationType"));
|
||||
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command
|
||||
.integerValueOfParameterNamed("repaymentFrequencyType"));
|
||||
final PeriodFrequencyType interestFrequencyType = PeriodFrequencyType.fromInt(command
|
||||
|
||||
Reference in New Issue
Block a user