[ 
https://issues.apache.org/jira/browse/FINERACT-628?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16655132#comment-16655132
 ] 

ASF GitHub Bot commented on FINERACT-628:
-----------------------------------------

ShruthiRajaram closed pull request #467: FINERACT-628 Savings account APIs for 
Self Service App
URL: https://github.com/apache/fineract/pull/467
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm
index 9a87171cc..052ba098c 100644
--- a/api-docs/apiLive.htm
+++ b/api-docs/apiLive.htm
@@ -3667,10 +3667,26 @@ <h2 class="flybar-button">Self Service</h2>
                                                        </tr>
                                                        <tr>
                                                                <td><a 
href="#selfsavings">Savings</a></td>
+                                                               
<td>self/savingsaccounts/template?clientId={clientId}&productId={productId}</td>
+                                                               <td></td>
+                                                               <td><a 
href="#selfsavings_template">Retrieve Savings Application Template</a></td>
+                                                               <td></td>
+                                                               <td></td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td></td>
+                                                               
<td>self/savingsaccounts</td>
+                                                               <td><a 
href="#selfsavingssubmission">Submit new Savings Application</a></td>
+                                                               <td></td>
+                                                               <td></td>
+                                                               <td></td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td></td>
                                                                
<td>self/savingsaccounts/{accountId}</td>
                                                                <td></td>
                                                                <td><a 
href="#selfsavings">Retrieve a Savings Account</a></td>
-                                                               <td></td>
+                                                               <td><a 
href="#selfsavings_update">Update Savings Account</a></td>
                                                                <td></td>
                                                        </tr>
                                                        <tr>
@@ -46695,6 +46711,100 @@ <h4>Retrieve a Loan Charge</h4>
                                </div>
                        </div>
 
+                       
+       <a id="selfsavingssubmission" name="selfsavingssubmission" 
class="old-syle-anchor">&nbsp;</a>
+       <div class="method-section">
+           <div class="method-description">
+               <h2>Submit new savings application</h2>
+               <br/>
+               <table class=matrixHeading>
+                   <tr class="matrixHeadingBG"><td><div 
class="fineractHeading2">Mandatory Fields</div></td></tr>
+                   <tr class=alt><td>clientId, productId, 
submittedOnDate</td></tr>
+               </table>
+               <br/>
+               <table class=matrixHeading>
+                   <tr class="matrixHeadingBG"><td><div 
class="fineractHeading2">Optional Fields</div></td></tr>
+                   <tr class=alt><td>accountNo, externalId, 
fieldOfficerId</td></tr>
+               </table>
+               <br/>
+               <table class=matrixHeading>
+                   <tr class="matrixHeadingBG"><td><div 
class="fineractHeading2">Inherited from Product (if not 
provided)</div></td></tr>
+                   <tr class=alt><td>nominalAnnualInterestRate, 
interestCompoundingPeriodType, interestCalculationType, 
interestCalculationDaysInYearType, minRequiredOpeningBalance, 
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, 
allowOverdraft, overdraftLimit, withHoldTax</td>
+                       </tr>
+               </table>
+            <br/>
+           </div>
+           <div class="method-example">
+               <p>Minimal request: accountNo auto generated, remaining details 
inherited from savings product.</p>
+               <code class="method-declaration">POST https://Domain 
Name/api/v1/self/savingsaccounts</code>
+               <code class="method-request">POST self/savingsaccount
+Content-Type: application/json
+Request Body:
+{  
+       "productId":3,
+       "clientId":"14",
+       "locale":"en",
+       "dateFormat":"dd MMMM yyyy",
+       "submittedOnDate":"09 July 2018"
+}
+                       </code>
+                        <code class="method-response">
+{  
+       "officeId":1,
+       "clientId":14,
+       "savingsId":10,
+       "resourceId":10
+}
+               </code>
+                       
+                       <p>Full request:Below details override details from 
savings product (except currency).</p>
+                       <code class="method-request">POST self/savingsaccount
+Content-Type: application/json
+Request Body:
+{  
+       "productId":1,
+       "nominalAnnualInterestRate":9.5,
+       "minRequiredOpeningBalance":1000,
+       "lockinPeriodFrequency":1,
+       "withdrawalFeeForTransfers":true,
+       "allowOverdraft":true,
+       "overdraftLimit":"10000",
+       "nominalAnnualInterestRateOverdraft":"5",
+       "minOverdraftForInterestCalculation":"1000",
+       "enforceMinRequiredBalance":false,
+       "withHoldTax":false,
+       "interestCompoundingPeriodType":1,
+       "interestPostingPeriodType":4,
+       "interestCalculationType":1,
+       "interestCalculationDaysInYearType":365,
+       "lockinPeriodFrequencyType":1,
+       "fieldOfficerId":1,
+       "externalId":"126",
+       "submittedOnDate":"11 July 2018",
+       "locale":"en",
+       "dateFormat":"dd MMMM yyyy",
+       "monthDayFormat":"dd MMM",
+       "charges":[  
+               {  
+               "chargeId":3,
+               "amount":2
+               }
+       ],
+       "clientId":"14"
+}
+                       </code>
+               <code class="method-response">
+{  
+       "officeId":1,
+       "clientId":14,
+       "savingsId":9,
+       "resourceId":9
+}
+               </code>
+           </div>
+       </div>
+
+       
        <a id="selfsavings" name="selfsavings" 
class="old-syle-anchor">&nbsp;</a>
        <div class="method-section">
            <div class="method-description">
@@ -46785,6 +46895,364 @@ <h4>Arguments</h4>
                </code>
            </div>
        </div>
+       
+       <a id="selfsavings_update" name="selfsavings_update" 
class="old-syle-anchor">&nbsp;</a>
+       <div class="method-section">
+           <div class="method-description">
+               <h2>Modify a savings application</h2>
+               <p>Savings application can only be modified when in 'Submitted 
and pending approval' state. Once the application is approved, the details 
cannot be changed using this method. Specific api endpoints will be created to 
allow change of interest detail such as rate, compounding period, posting 
period etc</p>
+           </div>
+           <div class="method-example">
+               <code class="method-declaration">PUT https://Domain 
Name/api/v1/self/savingsaccounts/{accountsId}</code>
+               <code class="method-request">PUT self/savingsaccounts/1
+Content-Type: application/json
+No Request Body:
+{
+       "productId":1,
+       "clientId":14
+}
+               </code>
+               <code class="method-response">
+{
+    "officeId": 1,
+    "clientId": 14,
+    "savingsId": 11,
+    "resourceId": 11,
+    "changes": {
+        "productId": 1
+    }
+}
+               </code>
+           </div>
+       </div>
+
+       <a id="selfsavings_template" name="selfsavings_template" 
class="old-syle-anchor">&nbsp;</a>
+       <div class="method-section">
+           <div class="method-description">
+               <h2>Retrieve Savings Account Template:</h2>
+               <h4>Arguments</h4>
+               <dl class="argument-list">
+                   <dt>clientId</dt>
+                   <dd>Integer <span>mandatory</span></dd>
+                   <dt>productId</dt>
+                   <dd>Integer <span>optional</span></dd>
+                   <dd>If entered, productId, productName and selectedProduct 
fields are returned.</dd>
+               </dl>
+               <p>Example Requests: </p>
+               <div 
class=apiClick>self/savingsaccounts/template?clientId=14</div>
+               <br><br>
+               <div 
class=apiClick>self/savingsaccounts/template?clientId=14&productId=2</div>
+           </div>
+           <div class="method-example">
+               <code class="method-declaration">GET https://Domain 
Name/api/v1/self/savingsaccounts/template?clientId={clientId}</code>
+                       <code class="method-response">
+{
+    "clientId": 14,
+    "clientName": "Bheem",
+    "withdrawalFeeForTransfers": false,
+    "allowOverdraft": false,
+    "enforceMinRequiredBalance": false,
+    "withHoldTax": false,
+    "isDormancyTrackingActive": false,
+    "productOptions": [
+        {
+            "id": 1,
+            "name": "Voluntary savings",
+            "withdrawalFeeForTransfers": false,
+            "allowOverdraft": false,
+            "enforceMinRequiredBalance": false,
+            "withHoldTax": false
+        },
+        {
+            "id": 2,
+            "name": "Savings",
+            "withdrawalFeeForTransfers": false,
+            "allowOverdraft": false,
+            "enforceMinRequiredBalance": false,
+            "withHoldTax": false
+        },
+        {
+            "id": 3,
+            "name": "Savings Product",
+            "withdrawalFeeForTransfers": false,
+            "allowOverdraft": false,
+            "enforceMinRequiredBalance": false,
+            "withHoldTax": false
+        }
+    ],
+    "chargeOptions": [
+        {
+            "id": 3,
+            "name": "Saving Accounts Processing Fee",
+            "active": true,
+            "penalty": false,
+            "currency": {
+                "code": "USD",
+                "name": "US Dollar",
+                "decimalPlaces": 2,
+                "displaySymbol": "$",
+                "nameCode": "currency.USD",
+                "displayLabel": "US Dollar ($)"
+            },
+            "amount": 2,
+            "chargeTimeType": {
+                "id": 3,
+                "code": "chargeTimeType.savingsActivation",
+                "value": "Savings Activation"
+            },
+            "chargeAppliesTo": {
+                "id": 2,
+                "code": "chargeAppliesTo.savings",
+                "value": "Savings"
+            },
+            "chargeCalculationType": {
+                "id": 1,
+                "code": "chargeCalculationType.flat",
+                "value": "Flat"
+            },
+            "chargePaymentMode": {
+                "id": 0,
+                "code": "chargepaymentmode.regular",
+                "value": "Regular"
+            }
+        }
+    ]
+}
+                       </code>
+           </div>
+
+           <div class="method-example">
+               <code class="method-declaration">GET https://Domain 
Name/api/v1/self/savingsaccounts/template?clientId={clientId}&productId={productId}</code>
+                       <code class="method-response">
+{
+    "clientId": 14,
+    "clientName": "Bheem",
+    "savingsProductId": 2,
+    "savingsProductName": "Savings",
+    "timeline": {},
+    "currency": {
+        "code": "USD",
+        "name": "US Dollar",
+        "decimalPlaces": 2,
+        "inMultiplesOf": 1,
+        "displaySymbol": "$",
+        "nameCode": "currency.USD",
+        "displayLabel": "US Dollar ($)"
+    },
+    "nominalAnnualInterestRate": 5,
+    "interestCompoundingPeriodType": {
+        "id": 1,
+        "code": 
"savings.interest.period.savingsCompoundingInterestPeriodType.daily",
+        "value": "Daily"
+    },
+    "interestPostingPeriodType": {
+        "id": 4,
+        "code": 
"savings.interest.posting.period.savingsPostingInterestPeriodType.monthly",
+        "value": "Monthly"
+    },
+    "interestCalculationType": {
+        "id": 1,
+        "code": "savingsInterestCalculationType.dailybalance",
+        "value": "Daily Balance"
+    },
+    "interestCalculationDaysInYearType": {
+        "id": 365,
+        "code": "savingsInterestCalculationDaysInYearType.days365",
+        "value": "365 Days"
+    },
+    "minRequiredOpeningBalance": 1000,
+    "withdrawalFeeForTransfers": false,
+    "allowOverdraft": false,
+    "enforceMinRequiredBalance": false,
+    "withHoldTax": false,
+    "isDormancyTrackingActive": false,
+    "charges": [],
+    "productOptions": [
+        {
+            "id": 1,
+            "name": "Voluntary savings",
+            "withdrawalFeeForTransfers": false,
+            "allowOverdraft": false,
+            "enforceMinRequiredBalance": false,
+            "withHoldTax": false
+        },
+        {
+            "id": 2,
+            "name": "Savings",
+            "withdrawalFeeForTransfers": false,
+            "allowOverdraft": false,
+            "enforceMinRequiredBalance": false,
+            "withHoldTax": false
+        },
+        {
+            "id": 3,
+            "name": "Savings Product",
+            "withdrawalFeeForTransfers": false,
+            "allowOverdraft": false,
+            "enforceMinRequiredBalance": false,
+            "withHoldTax": false
+        }
+    ],
+    "fieldOfficerOptions": [
+        {
+            "id": 1,
+            "firstname": "Aliya",
+            "lastname": "A",
+            "displayName": "A, Aliya",
+            "officeId": 1,
+            "officeName": "Head Office",
+            "isLoanOfficer": true,
+            "isActive": true
+        }
+    ],
+    "interestCompoundingPeriodTypeOptions": [
+        {
+            "id": 1,
+            "code": 
"savings.interest.period.savingsCompoundingInterestPeriodType.daily",
+            "value": "Daily"
+        },
+        {
+            "id": 4,
+            "code": 
"savings.interest.period.savingsCompoundingInterestPeriodType.monthly",
+            "value": "Monthly"
+        },
+        {
+            "id": 5,
+            "code": 
"savings.interest.period.savingsCompoundingInterestPeriodType.quarterly",
+            "value": "Quarterly"
+        },
+        {
+            "id": 6,
+            "code": 
"savings.interest.period.savingsCompoundingInterestPeriodType.biannual",
+            "value": "Semi-Annual"
+        },
+        {
+            "id": 7,
+            "code": 
"savings.interest.period.savingsCompoundingInterestPeriodType.annual",
+            "value": "Annually"
+        }
+    ],
+    "interestPostingPeriodTypeOptions": [
+        {
+            "id": 4,
+            "code": 
"savings.interest.posting.period.savingsPostingInterestPeriodType.monthly",
+            "value": "Monthly"
+        },
+        {
+            "id": 5,
+            "code": 
"savings.interest.posting.period.savingsPostingInterestPeriodType.quarterly",
+            "value": "Quarterly"
+        },
+        {
+            "id": 6,
+            "code": 
"savings.interest.posting.period.savingsPostingInterestPeriodType.biannual",
+            "value": "BiAnnual"
+        },
+        {
+            "id": 7,
+            "code": 
"savings.interest.posting.period.savingsPostingInterestPeriodType.annual",
+            "value": "Annually"
+        }
+    ],
+    "interestCalculationTypeOptions": [
+        {
+            "id": 1,
+            "code": "savingsInterestCalculationType.dailybalance",
+            "value": "Daily Balance"
+        },
+        {
+            "id": 2,
+            "code": "savingsInterestCalculationType.averagedailybalance",
+            "value": "Average Daily Balance"
+        }
+    ],
+    "interestCalculationDaysInYearTypeOptions": [
+        {
+            "id": 360,
+            "code": "savingsInterestCalculationDaysInYearType.days360",
+            "value": "360 Days"
+        },
+        {
+            "id": 365,
+            "code": "savingsInterestCalculationDaysInYearType.days365",
+            "value": "365 Days"
+        }
+    ],
+    "lockinPeriodFrequencyTypeOptions": [
+        {
+            "id": 0,
+            "code": "savings.lockin.savingsPeriodFrequencyType.days",
+            "value": "Days"
+        },
+        {
+            "id": 1,
+            "code": "savings.lockin.savingsPeriodFrequencyType.weeks",
+            "value": "Weeks"
+        },
+        {
+            "id": 2,
+            "code": "savings.lockin.savingsPeriodFrequencyType.months",
+            "value": "Months"
+        },
+        {
+            "id": 3,
+            "code": "savings.lockin.savingsPeriodFrequencyType.years",
+            "value": "Years"
+        }
+    ],
+    "withdrawalFeeTypeOptions": [
+        {
+            "id": 1,
+            "code": "savingsWithdrawalFeesType.flat",
+            "value": "Flat"
+        },
+        {
+            "id": 2,
+            "code": "savingsWithdrawalFeesType.percent.of.amount",
+            "value": "% of Amount"
+        }
+    ],
+    "chargeOptions": [
+        {
+            "id": 3,
+            "name": "Saving Accounts Processing Fee",
+            "active": true,
+            "penalty": false,
+            "currency": {
+                "code": "USD",
+                "name": "US Dollar",
+                "decimalPlaces": 2,
+                "displaySymbol": "$",
+                "nameCode": "currency.USD",
+                "displayLabel": "US Dollar ($)"
+            },
+            "amount": 2,
+            "chargeTimeType": {
+                "id": 3,
+                "code": "chargeTimeType.savingsActivation",
+                "value": "Savings Activation"
+            },
+            "chargeAppliesTo": {
+                "id": 2,
+                "code": "chargeAppliesTo.savings",
+                "value": "Savings"
+            },
+            "chargeCalculationType": {
+                "id": 1,
+                "code": "chargeCalculationType.flat",
+                "value": "Flat"
+            },
+            "chargePaymentMode": {
+                "id": 0,
+                "code": "chargepaymentmode.regular",
+                "value": "Regular"
+            }
+        }
+    ]
+}
+                       </code>
+           </div>
+       </div>
 
 <a id="selfsavingstransaction" name="selfsavingstransaction" 
class="old-syle-anchor">&nbsp;</a>
        <div class="method-section">
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/savings/api/SelfSavingsApiResource.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/savings/api/SelfSavingsApiResource.java
index bfcd11d05..9eff7e7f8 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/savings/api/SelfSavingsApiResource.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/savings/api/SelfSavingsApiResource.java
@@ -18,9 +18,13 @@
  */
 package org.apache.fineract.portfolio.self.savings.api;
 
+import java.util.HashMap;
+
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
@@ -30,10 +34,13 @@
 import javax.ws.rs.core.UriInfo;
 
 import 
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.apache.fineract.portfolio.client.exception.ClientNotFoundException;
 import 
org.apache.fineract.portfolio.savings.api.SavingsAccountChargesApiResource;
 import 
org.apache.fineract.portfolio.savings.api.SavingsAccountTransactionsApiResource;
 import org.apache.fineract.portfolio.savings.api.SavingsAccountsApiResource;
 import 
org.apache.fineract.portfolio.savings.exception.SavingsAccountNotFoundException;
+import 
org.apache.fineract.portfolio.self.client.service.AppuserClientMapperReadService;
+import 
org.apache.fineract.portfolio.self.savings.data.SelfSavingsAccountConstants;
 import 
org.apache.fineract.portfolio.self.savings.data.SelfSavingsDataValidator;
 import 
org.apache.fineract.portfolio.self.savings.service.AppuserSavingsMapperReadService;
 import org.apache.fineract.useradministration.domain.AppUser;
@@ -52,6 +59,7 @@
        private final SavingsAccountTransactionsApiResource 
savingsAccountTransactionsApiResource;
        private final AppuserSavingsMapperReadService 
appuserSavingsMapperReadService;
        private final SelfSavingsDataValidator dataValidator;
+       private final AppuserClientMapperReadService 
appUserClientMapperReadService;
 
        @Autowired
        public SelfSavingsApiResource(
@@ -60,13 +68,15 @@ public SelfSavingsApiResource(
                        final SavingsAccountChargesApiResource 
savingsAccountChargesApiResource,
                        final SavingsAccountTransactionsApiResource 
savingsAccountTransactionsApiResource,
                        final AppuserSavingsMapperReadService 
appuserSavingsMapperReadService,
-                       final SelfSavingsDataValidator dataValidator) {
+                       final SelfSavingsDataValidator dataValidator,
+                       final AppuserClientMapperReadService 
appUserClientMapperReadService) {
                this.context = context;
                this.savingsAccountsApiResource = savingsAccountsApiResource;
                this.savingsAccountChargesApiResource = 
savingsAccountChargesApiResource;
                this.savingsAccountTransactionsApiResource = 
savingsAccountTransactionsApiResource;
                this.appuserSavingsMapperReadService = 
appuserSavingsMapperReadService;
                this.dataValidator = dataValidator;
+               this.appUserClientMapperReadService = 
appUserClientMapperReadService;
        }
 
        @GET
@@ -145,4 +155,51 @@ private void validateAppuserSavingsAccountMapping(final 
Long accountId) {
                }
        }
 
+       @GET
+       @Path("template")
+       @Consumes({ MediaType.APPLICATION_JSON })
+       @Produces({ MediaType.APPLICATION_JSON })
+       public String template(@QueryParam("clientId") final Long clientId, 
@QueryParam("productId") final Long productId,
+                       final String apiRequestBodyAsJson, @Context final 
UriInfo uriInfo) {
+
+               validateAppuserClientsMapping(clientId);
+               Long groupId = null;
+               boolean staffInSelectedOfficeOnly = false;
+               return this.savingsAccountsApiResource.template(clientId, 
groupId, productId, staffInSelectedOfficeOnly,
+                               uriInfo);
+
+       }
+
+       @POST
+       @Consumes({ MediaType.APPLICATION_JSON })
+       @Produces({ MediaType.APPLICATION_JSON })
+       public String submitSavingsAccountApplication(@QueryParam("command") 
final String commandParam,
+                       @Context final UriInfo uriInfo, final String 
apiRequestBodyAsJson) {
+
+               HashMap<String, Object> parameterMap = 
this.dataValidator.validateSavingsApplication(apiRequestBodyAsJson);
+               final Long clientId = (Long) 
parameterMap.get(SelfSavingsAccountConstants.clientIdParameterName);
+               validateAppuserClientsMapping(clientId);
+               return 
this.savingsAccountsApiResource.submitApplication(apiRequestBodyAsJson);
+       }
+
+       @PUT
+       @Path("{accountId}")
+       @Consumes({ MediaType.APPLICATION_JSON })
+       @Produces({ MediaType.APPLICATION_JSON })
+       public String modifySavingsAccountApplication(@PathParam("accountId") 
final Long accountId,
+                       @QueryParam("command") final String commandParam, final 
String apiRequestBodyAsJson) {
+
+               validateAppuserSavingsAccountMapping(accountId);
+               
this.dataValidator.validateSavingsApplication(apiRequestBodyAsJson);
+               return this.savingsAccountsApiResource.update(accountId, 
apiRequestBodyAsJson, commandParam);
+       }
+
+       private void validateAppuserClientsMapping(final Long clientId) {
+               AppUser user = this.context.authenticatedUser();
+               final boolean mappedClientId = 
this.appUserClientMapperReadService.isClientMappedToUser(clientId, 
user.getId());
+               if (!mappedClientId) {
+                       throw new ClientNotFoundException(clientId);
+               }
+       }
+
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/savings/data/SelfSavingsAccountConstants.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/savings/data/SelfSavingsAccountConstants.java
new file mode 100644
index 000000000..ec37bbbcf
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/savings/data/SelfSavingsAccountConstants.java
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.portfolio.self.savings.data;
+
+public class SelfSavingsAccountConstants {
+
+       public static final String savingsAccountResource = "savings";
+       public static final String clientIdParameterName = "clientId";
+       public static final String productIdParameterName = "productId";
+
+}
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/savings/data/SelfSavingsDataValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/savings/data/SelfSavingsDataValidator.java
index 3cbadf9e6..7ed14ab87 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/savings/data/SelfSavingsDataValidator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/savings/data/SelfSavingsDataValidator.java
@@ -20,19 +20,36 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
 import javax.ws.rs.core.UriInfo;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.fineract.infrastructure.core.api.ApiParameterHelper;
+import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
+import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
+import 
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
 import 
org.apache.fineract.infrastructure.core.exception.UnsupportedParameterException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
 import org.apache.fineract.portfolio.savings.SavingsApiConstants;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import com.google.gson.JsonElement;
+
 @Component
 public class SelfSavingsDataValidator {
+       
+       private final FromJsonHelper fromApiJsonHelper;
+
+       @Autowired
+       public SelfSavingsDataValidator(final FromJsonHelper fromApiJsonHelper) 
{
+               this.fromApiJsonHelper = fromApiJsonHelper;
+       }
 
        private static final Set<String> allowedAssociationParameters = new 
HashSet<>(
                        Arrays.asList(SavingsApiConstants.transactions,
@@ -82,5 +99,32 @@ private void validateTemplate(final UriInfo uriInfo,
                        unsupportedParams.add("template");
                }
        }
+       
+       public HashMap<String, Object> validateSavingsApplication(final String 
json) {
+               if (StringUtils.isBlank(json)) {
+                       throw new InvalidJsonException();
+               }
+
+               final List<ApiParameterError> dataValidationErrors = new 
ArrayList<>();
+               final DataValidatorBuilder baseDataValidator = new 
DataValidatorBuilder(dataValidationErrors)
+                               
.resource(SelfSavingsAccountConstants.savingsAccountResource);
+
+               final JsonElement element = this.fromApiJsonHelper.parse(json);
+
+               final Long clientId = 
this.fromApiJsonHelper.extractLongNamed(SelfSavingsAccountConstants.clientIdParameterName,
+                               element);
+               
baseDataValidator.reset().parameter(SelfSavingsAccountConstants.clientIdParameterName).value(clientId).notNull()
+                               .longGreaterThanZero();
+
+               if (!dataValidationErrors.isEmpty()) {
+                       throw new 
PlatformApiDataValidationException(dataValidationErrors);
+               }
+
+               HashMap<String, Object> parameterMap = new HashMap<>();
+               
parameterMap.put(SelfSavingsAccountConstants.clientIdParameterName, clientId);
+
+               return parameterMap;
+
+       }
 
 }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


> Creation Of API's for Self-Service App
> --------------------------------------
>
>                 Key: FINERACT-628
>                 URL: https://issues.apache.org/jira/browse/FINERACT-628
>             Project: Apache Fineract
>          Issue Type: New Feature
>            Reporter: Saksham Handu
>            Assignee: Shruthi  M R
>            Priority: Major
>
> List Of API's needed are mentioned below,
> 1) Support for applying for for savings accounts
>  2) Support for viewing share accounts
>  3) Support for adding guarantors
>  4) Support for editing user details. 
>  5) Support for viewing reports
>  6) Support for surveys
> 7) Support for Applying for new Shares Account
> 8) Support for uploading new Client's Image
> 9) Support for the list of Loan, Savings, Shares product along with their 
> details



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to