ShruthiRajaram closed pull request #485: FINERACT-628 Products APIs
URL: https://github.com/apache/fineract/pull/485
 
 
   

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 00751bc2c..9e10be258 100644
--- a/api-docs/apiLive.htm
+++ b/api-docs/apiLive.htm
@@ -3617,6 +3617,40 @@ <h2 class="flybar-button">Self Service</h2>
                                                                <td></td>
                                                                <td></td>
                                                        </tr>
+                                                       <tr>
+                                                               <td><a 
href="#self_loanproducts">Loan Product</a></td>
+                                                               
<td>self/loanproducts?clientId={clientId}</td>
+                                                               <td></td>
+                                                               <td><a 
href="#self_loanproducts_list">List Loan Products</a></td>
+                                                               <td></td>
+                                                               <td></td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td></td>
+                                                               
<td>self/loanproducts/{productId}?clientId={clientId}</td>
+                                                               <td></td>
+                                                               <td><a 
href="#self_loanproducts_retrieve">Retrieve a Loan
+                                                                               
Product</a></td>
+                                                               <td></td>
+                                                               <td></td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td><a 
href="#self_savingsproducts">Savings Product</a></td>
+                                                               
<td>self/savingsproducts?clientId={clientId}</td>
+                                                               <td></td>
+                                                               <td><a 
href="#self_savingsproducts_list">List Savings products</a></td>
+                                                               <td></td>
+                                                               <td></td>
+                                                       </tr>
+
+                                                       <tr>
+                                                               <td></td>
+                                                               
<td>self/savingsproducts/{productId}?clientId={clientId}</td>
+                                                               <td></td>
+                                                               <td><a 
href="#self_savingsproducts_retrieve">Retrieve a savings product</a></td>
+                                                               <td></td>
+                                                               <td></td>
+                                                       </tr>
                                                        <tr>
                                                                <td></td>
                                                                
<td>self/clients/{clientId}/images</td>
@@ -3625,6 +3659,22 @@ <h2 class="flybar-button">Self Service</h2>
                                                                <td></td>
                                                                <td><a 
href="#self_client_image_delete">Delete client image</a></td>
                                                        </tr>
+                                                       <tr>
+                                                               <td><a 
href="#self_shareproducts_list">Share Product</a></td>
+                                                               
<td>self/shareproducts?clientId={clientId}</td>
+                                                               <td></td>
+                                                               <td><a 
href="#self_shareproducts_list">List Share products</a></td>
+                                                               <td></td>
+                                                               <td></td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td></td>
+                                                               
<td>self/shareproducts/{productId}?clientId={clientId}</td>
+                                                               <td></td>
+                                                               <td><a 
href="#self_shareproducts_retrieve">Retrieve a share product</a></td>
+                                                               <td></td>
+                                                               <td></td>
+                                                       </tr>
                                                        <tr>
                                                                <td><a 
href="#selfloantemplate">Loans</a></td>
                                                                
<td>self/loans/template?templateType=individual</td>
@@ -49222,11 +49272,1148 @@ <h4>Delete an client's Image</h4>
   "resourceId": 14,
   "changes": {},
   "resourceIdentifier": "14"
-}
+}                                      </code>
+                               </div>
+                       </div>
+<a id="self_loanproducts" name="self_loanproducts" 
class="old-syle-anchor">&nbsp;</a>
+                       <div class="method-section">
+                               <div class="method-description">
+                                       <h3>Loan Products</h3>
+                                       
+                                       <table class=matrixHeading>
+                                               <tr class="matrixHeadingBG">
+                                                       <td><div 
class="fineractHeading2">Field Descriptions</div></td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       <td>name</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Name associated with loan product on system.</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       <td>shortName</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Short name associated with a loan product. <br>
+                                                               An abbreviated 
version of the name, used in reports or menus where space is limited, such as 
Collection Sheets.
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       <td>description</td>
+                                               </tr>
+                                               <tr>
+                                                       <td class=fielddesc>For 
providing helpful description of product offering.</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       <td>fundId</td>
+                                               </tr>
+                                               <tr>
+                                                       <td class=fielddesc>For 
associating a loan product with a given fund by default.</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>includeInBorrowerCycle</td>
+                                               </tr>
+                                               <tr>
+                                                       <td class=fielddesc>It 
is a flag, Used to denote whether the loans should include in loan cycle 
counter or not.</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>useBorrowerCycle</td>
+                                               </tr>
+                                               <tr>
+                                                       <td class=fielddesc>It 
is a flag, Used to denote whether the loans should depend on <br>borrower loan 
cycle counter or not.</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       <td>currencyCode</td>
+                                               </tr>
+                                               <tr>
+                                                       <td class=fielddesc>A 
three letter ISO code of currency.</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>digitsAfterDecimal</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Override the currency default value for digitsAfterDecimal.</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       <td>inMultiplesOf</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Override the default value for rounding currency to multiples 
of value provided.</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>installmentAmountInMultiplesOf</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Override the default value for rounding instalment amount to 
multiples of value provided.</td>
+                                               </tr>
+
+                                               <tr class=alt>
+                                                       <td>principal</td>
+                                               </tr>
+                                               <tr>
+                                                       <td class=fielddesc>The 
loan amount to be disbursed to through loan.</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>numberOfRepayments</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Number of installments to repay.<br>
+                                                               Used like: 
<b>numberOfRepayments</b> Every <i>repaymentEvery</i>
+                                                               
<i>repaymentFrequencyType</i><br> e.g. <b>10</b> (repayments) Every 12 Weeks
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       <td>repaymentEvery</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Used like: numberOfRepayments Every
+                                                               
<b>repaymentEvery</b> repaymentFrequencyType<br> e.g. 10
+                                                               (repayments) 
Every <b>12</b> Weeks
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>repaymentFrequencyType</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Used like: <i>numberOfRepayments</i> Every
+                                                               repaymentEvery 
<b>repaymentFrequencyType</b><br> e.g. 10
+                                                               (repayments) 
Every 12 <b>Weeks</b> <br>
+                                                               <span>Example 
Values:</span> 0=Days, 1=Weeks, 2=Months
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>interestRatePerPeriod</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Interest Rate.<br> Used like:
+                                                               
<b>interestRatePerPeriod</b> % interestRateFrequencyType - interestType<br>
+                                                               e.g. 
<b>12.0000</b>% Per year - Declining Balance
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>interestRateFrequencyType</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Used like: interestRatePerPeriod%
+                                                               
interestRateFrequencyType - interestType<br> e.g. 12.0000%
+                                                               <b>Per year</b> 
- Declining Balance <br>
+                                                       <span>Example 
Values:</span> 2=Per month, 3=Per year
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>amortizationType</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc><span>Example Values:</span> 0=Equal
+                                                               principle 
payments, 1=Equal installments</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       <td>interestType</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Used like: interestRatePerPeriod%
+                                                               
interestRateFrequencyType - interestType<br> e.g. 12.0000%
+                                                               Per year - 
<b>Declining Balance</b> <br>
+                                                       <span>Example 
Values:</span> 0=Declining Balance, 1=Flat
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>interestCalculationPeriodType</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc><span>Example Values:</span> 0=Daily, 1=Same as repayment 
period</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>allowPartialPeriodInterestCalcualtion</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>This value will be supported along with 
interestCalculationPeriodType as Same as repayment period to calculate interest 
for partial periods.
+                                                       <span>Example:</span> 
Interest charged from is 5th of April , Principal is 10000 and interest is 1% 
per month then the interest will be (10000 * 1%)* (25/30) , it calculates for 
the month first then calculates exact periods between start date and end 
date(can be a decimal)
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>inArrearsTolerance</td>
+                                               </tr>
+                                               <tr>
+                                                       <td class=fielddesc>The 
amount that can be 'waived' at end
+                                                               of all loan 
payments because it is too small to worry about.<br>
+                                                               This is also 
the tolerance amount assessed when determining if a
+                                                               loan is in 
arrears.
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>principalVariationsForBorrowerCycle,interestRateVariationsForBorrowerCycle,<br>numberOfRepaymentVariationsForBorrowerCycle</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Variations for loan, based on borrower cycle number
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>minimumDaysBetweenDisbursalAndFirstRepayment</td>
+                                               </tr>
+                                               <tr>
+                                                       <td class=fielddesc>The 
minimum number of days allowed between a Loan disbursal and its first repayment.
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>principalThresholdForLastInstalment</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Field represents percentage of current instalment principal 
amount for comparing against principal outstanding to add another repayment 
instalment.  If the outstanding principal amount is less then calculated 
amount, remaining outstanding amount will be added to current instalment. 
Default value for multi disburse loan is 50% and non-multi disburse loan is 0%
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>canDefineInstallmentAmount</td>
+                                               </tr>
+                                               <tr>
+                                                       <td class=fielddesc>if 
provided as true, then fixed instalment amount can be provided from loan 
account.
+                                                       </td>
+                                               </tr>
+
+
+
+<tr class=alt>
+       <td>transactionProcessingStrategyId</td>
+</tr>
+<tr>
+       <td class=fielddesc>
+An enumeration that indicates the type of transaction processing strategy to 
be used. This relates to functionality that is also known as <b>Payment 
Application Logic</b>.
+
+<p>A number of out of the box approaches exist, some are custom to specific 
MFIs, some are more general and indicate the order in which payments are 
processed.</p>
+
+<p>Refer to the <a href="#paymentapplicationlogic">Payment Application Logic / 
Transaction Processing Strategy<a> section in the appendix for more detailed 
overview of each available <b>payment application logic</b> provided out of the 
box.</p>
+
+<i>List of current approaches</i>:<br/>
+<ul>
+       <li>1 = Mifos style (Similar to Old Mifos)</li>
+       <li>2 = Heavensfamily (Custom MFI approach)</li>
+       <li>3 = Creocore (Custom MFI approach)</li>
+       <li>4 = RBI (India)</li>
+       <li>5 = Principal Interest Penalties Fees Order</li>
+       <li>6 = Interest Principal Penalties Fees Order</li>
+    <li>7 = Early Payment Strategy</li>
+</ul>
+       </td>
+</tr>
+                                               <tr class=alt>
+                                                       
<td>graceOnPrincipalPayment</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Optional: Integer - represents the number of repayment periods 
that grace should apply to the principal component of a repayment period.
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>graceOnInterestPayment</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Optional: Integer - represents the number of repayment periods 
that grace should apply to the interest component of a repayment period. 
Interest is still calculated but offset to later repayment periods.
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>graceOnInterestCharged</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Optional: Integer - represents the number of repayment periods 
that should be interest-free.
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>graceOnArrearsAgeing</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Optional: Integer -  Used in Arrears calculation to only take 
into account loans that are more than graceOnArrearsAgeing days overdue.
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>overdueDaysForNPA</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Optional: Integer - represents the maximum number of days a 
Loan may
+                                                       be overdue before being 
classified as a NPA (non performing asset)
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>accountMovesOutOfNPAOnlyOnArrearsCompletion</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Optional: Boolean - if provided as true,  Loan Account moves 
out of NPA state only when all arrears are cleared
+                                                       </td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       <td>accountingRule</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Specifies if accounting is enabled for the particular
+                                                               product and the 
type of the accounting rule to be used
+                                                               <span>Example 
Values:</span>1=NONE, 2=CASH_BASED, 3=ACCRUAL_PERIODIC, 4=ACCRUAL_UPFRONT</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>isInterestRecalculationEnabled</td>
+                                               </tr>
+                                               <tr>
+                                                       <td class=fielddesc>It 
is a flag, Used to denote whether interest recalculation is enabled or disabled 
for the particular product</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       <td>daysInYearType</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Specifies the number of days in a year. <br>
+                                                       <span>Example 
Values:</span>1=ACTUAL(Actual number of days in year), 360=360 DAYS, 364=364 
DAYS(52 WEEKS), 365=365 DAYS</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       <td>daysInMonthType</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Specifies the number of days in a month. <br>
+                                                       <span>Example 
Values:</span>1=ACTUAL(Actual number of days in month), 30=30 DAYS</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>interestRecalculationCompoundingMethod</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Specifies which amount portion should be added to principal for 
interest recalculation. <br>
+                                                       <span>Example 
Values:</span>0=NONE(Only on principal), 1=INTEREST(Principal+Interest), 
2=FEE(Principal+Fee), 3=FEE And INTEREST (Principal+Fee+Interest)</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>rescheduleStrategyMethod</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Specifies what action should perform on loan repayment schedule 
for advance payments. <br>
+                                                       <span>Example 
Values:</span>1=Reschedule next repayments, 2=Reduce number of installments, 
3=Reduce EMI amount</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>recalculationCompoundingFrequencyType</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Specifies effective date from which the compounding of interest 
or fee amounts will be considered in recalculation on late payment.<br>
+                                                       <span>Example 
Values:</span>1=Same as repayment period, 2=Daily, 3=Weekly, 4=Monthly</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>recalculationCompoundingFrequencyInterval</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Specifies compounding frequency interval for interest 
recalculation.<br>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>recalculationCompoundingFrequencyDate</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Specifies compounding frequency start date for interest 
recalculation.<br>
+                                               </tr>
+
+                                               <tr class=alt>
+                                                       
<td>recalculationRestFrequencyType</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Specifies effective date from which the late or advanced 
payment amounts will be considered in recalculation.<br>
+                                                       <span>Example 
Values:</span>1=Same as repayment period, 2=Daily, 3=Weekly, 4=Monthly</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>recalculationRestFrequencyInterval</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Specifies rest frequency interval for interest 
recalculation.<br>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>recalculationRestFrequencyDate</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Specifies rest frequency start date for interest 
recalculation.<br>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>preClosureInterestCalculationStrategy</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Specifies applicable days for interest calculation on pre 
closure of a loan.<br>
+                                                       <span>Example 
Values:</span>1=Calculate till pre closure date, 2=Calculate till rest 
frequency date</td>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>isArrearsBasedOnOriginalSchedule</td>
+                                               </tr>
+                                               <tr>
+                                                       <td class=fielddesc>If 
Specified as true, arrears will be identified based on original schedule.<br>
+                                               </tr>
+                                               <tr class=alt>
+                                                       
<td>allowAttributeOverrides</td>
+                                               </tr>
+                                               <tr>
+                                                       <td 
class=fielddesc>Specifies if select attributes may be overridden for individual 
loan accounts.<br>
+                                               </tr>
+                                       </table>
+                               </div>
+                       </div>
+
+                       <a id="self_loanproducts_list" 
name="self_loanproducts_list"
+                               class="old-syle-anchor">&nbsp;</a>
+                       <div class="method-section">
+                               <div class="method-description">
+                                       <h4>List Loan Products</h4>
+                                       <p>Example Requests:</p>
+                                       <div 
class=apiClick>self/loanproducts?clientId=1</div>
+                                       <br>
+                                       <br>
+                                       <div 
class=apiClick>self/loanproducts?fields=name,description&clientId=1</div>
+                               </div>
+                               <div class="method-example">
+                                       <code class="method-declaration">
+GET https://DomainName/api/v1/self/loanproducts?clientId={clientId}
+                                       </code>
+                                       <code class="method-response">
+[  
+   {  
+      "name":"Personal loan",
+      "description":"Loan",
+      "useBorrowerCycle":false,
+      "status":"loanProduct.active",
+      "allowVariableInstallments":false,
+      "minimumGap":0,
+      "maximumGap":0,
+      "daysInMonthType":{  
+         "code":"DaysInMonthType.actual",
+         "value":"Actual"
+      },
+      "daysInYearType":{  
+         "code":"DaysInYearType.actual",
+         "value":"Actual"
+      },
+      "isInterestRecalculationEnabled":false,
+      "canDefineInstallmentAmount":false,
+      "installmentAmountInMultiplesOf":1,
+      "principalVariationsForBorrowerCycle":[  
+
+      ],
+      "interestRateVariationsForBorrowerCycle":[  
+
+      ],
+      "numberOfRepaymentVariationsForBorrowerCycle":[  
+
+      ],
+      "multiDisburseLoan":false,
+      "maxTrancheCount":0,
+      "principalThresholdForLastInstallment":0,
+      "holdGuaranteeFunds":false,
+      "accountMovesOutOfNPAOnlyOnArrearsCompletion":false,
+      "allowAttributeOverrides":{  
+         "graceOnPrincipalAndInterestPayment":true,
+         "graceOnArrearsAgeing":true
+      },
+      "syncExpectedWithDisbursementDate":false
+   }
+]
                                        </code>
                                </div>
                        </div>
-       
+                       
+                       
+                       <a id="self_loanproducts_retrieve" 
name="self_loanproducts_retrieve"
+                               class="old-syle-anchor">&nbsp;</a>
+                       <div class="method-section">
+                               <div class="method-description">
+                                       <h4>Retrieve a Loan Product</h4>
+                                       <p>Example Requests:</p>
+                                       <div 
class=apiClick>self/loanproducts/1?clientId=1</div>
+                                       <br>
+                                       <br>
+                                       <div 
class=apiClick>self/loanproducts/1?fields=name,description&clientId=1</div>
+                               </div>
+                               <div class="method-example">
+                                       <code class="method-declaration">
+GET https://DomainName/api/v1/self/loanproducts/{productId}?clientId={clientId}
+                                       </code>
+                                       <code class="method-response">
+{
+  "id": 11,
+  "name": "advanced accounting",
+  "shortName": "ad11",
+  "includeInBorrowerCycle": true,
+  "useBorrowerCycle": true,
+  "status": "loanProduct.active",
+  "currency": {
+    "code": "USD",
+    "name": "US Dollar",
+    "decimalPlaces": 2,
+    "inMultiplesOf": 0,
+    "displaySymbol": "$",
+    "nameCode": "currency.USD",
+    "displayLabel": "US Dollar ($)"
+  },
+  "principal": 10000.000000,
+  "minPrincipal": 2000.000000,
+  "maxPrincipal": 15000.000000,
+  "numberOfRepayments": 7,
+  "repaymentEvery": 7,
+  "repaymentFrequencyType": {
+    "id": 0,
+    "code": "repaymentFrequency.periodFrequencyType.days",
+    "value": "Days"
+  },
+  "interestRatePerPeriod": 5.000000,
+  "interestRateFrequencyType": {
+    "id": 2,
+    "code": "interestRateFrequency.periodFrequencyType.months",
+    "value": "Per month"
+  },
+  "annualInterestRate": 60.000000,
+  "amortizationType": {
+    "id": 1,
+    "code": "amortizationType.equal.installments",
+    "value": "Equal installments"
+  },
+  "interestType": {
+    "id": 0,
+    "code": "interestType.declining.balance",
+    "value": "Declining Balance"
+  },
+  "interestCalculationPeriodType": {
+    "id": 1,
+    "code": "interestCalculationPeriodType.same.as.repayment.period",
+    "value": "Same as repayment period"
+  },
+  "transactionProcessingStrategyId": 1,
+  "transactionProcessingStrategyName": "Mifos style",
+  "charges": [],
+  "principalVariationsForBorrowerCycle": [
+    {
+      "id": 21,
+      "borrowerCycleNumber": 1,
+      "paramType": {
+        "id": 1,
+        "code": "LoanProductParamType.principal",
+        "value": "principal"
+      },
+      "valueConditionType": {
+        "id": 2,
+        "code": "LoanProductValueConditionType.equal",
+        "value": "equals"
+      },
+      "minValue": 2000.000000,
+      "maxValue": 20000.000000,
+      "defaultValue": 15000.000000
+    },
+    {
+      "id": 20,
+      "borrowerCycleNumber": 1,
+      "paramType": {
+        "id": 1,
+        "code": "LoanProductParamType.principal",
+        "value": "principal"
+      },
+      "valueConditionType": {
+        "id": 3,
+        "code": "LoanProductValueConditionType.greterthan",
+        "value": "greter than"
+      },
+      "minValue": 3000.000000,
+      "maxValue": 25000.000000,
+      "defaultValue": 20000.000000
+    }
+  ],
+  "interestRateVariationsForBorrowerCycle": [],
+  "numberOfRepaymentVariationsForBorrowerCycle": [],
+  "accountingRule": {
+    "id": 2,
+    "code": "accountingRuleType.cash",
+    "value": "CASH BASED"
+  },
+  "accountingMappings": {
+    "fundSourceAccount": {
+      "id": 1,
+      "name": "fund source",
+      "glCode": "01"
+    },
+    "loanPortfolioAccount": {
+      "id": 2,
+      "name": "Loan portfolio",
+      "glCode": "02"
+    },
+    "transfersInSuspenseAccount": {
+      "id": 3,
+      "name": "transfers",
+      "glCode": "03"
+    },
+    "interestOnLoanAccount": {
+      "id": 4,
+      "name": "income from interest",
+      "glCode": "04"
+    },
+    "incomeFromFeeAccount": {
+      "id": 8,
+      "name": "income from fees 2",
+      "glCode": "10"
+    },
+    "incomeFromPenaltyAccount": {
+      "id": 9,
+      "name": "income from penalities 2",
+      "glCode": "11"
+    },
+    "writeOffAccount": {
+      "id": 10,
+      "name": "loans written off 2",
+      "glCode": "12"
+    },
+    "overpaymentLiabilityAccount": {
+      "id": 11,
+      "name": "over payment",
+      "glCode": "13"
+    }
+  },
+  "paymentChannelToFundSourceMappings": [
+    {
+      "paymentType": {
+        "id": 10,
+        "name": "check"
+      },
+      "fundSourceAccount": {
+        "id": 1,
+        "name": "fund source",
+        "glCode": "01"
+      }
+    }
+  ],
+  "feeToIncomeAccountMappings": [
+    {
+      "charge": {
+        "id": 1,
+        "name": "flat install",
+        "active": false,
+        "penalty": false
+      },
+      "incomeAccount": {
+        "id": 8,
+        "name": "income from fees 2",
+        "glCode": "10"
+      }
+    },
+    {
+      "charge": {
+        "id": 2,
+        "name": "install per",
+        "active": false,
+        "penalty": false
+      },
+      "incomeAccount": {
+        "id": 4,
+        "name": "income from interest",
+        "glCode": "04"
+      }
+    },
+    {
+      "charge": {
+        "id": 5,
+        "name": "des charge",
+        "active": false,
+        "penalty": false
+      },
+      "incomeAccount": {
+        "id": 9,
+        "name": "income from penalities 2",
+        "glCode": "11"
+      }
+    },
+    
"multiDisburseLoan":true,"maxTrancheCount":3,"outstandingLoanBalance":36000.000000,
+    "overdueDaysForNPA":2,
+       "principalThresholdForLastInstalment":50
+  ]
+}
+                                       </code>
+                               </div>
+                       </div>
+                       
+<a id="self_savingsproducts" name="self_savingsproducts" 
class="old-syle-anchor">&nbsp;</a>
+       <div class="method-section">
+           <div class="method-description">
+               <h3>Savings Product:</h3>
+               <p>An MFIs savings product offerings are modeled using this 
API.</p>
+               <table class=matrixHeading>
+                   <tr class="matrixHeadingBG"><td><div 
class="fineractHeading2">Field Descriptions</div></td></tr>
+
+                               <tr class=alt><td>name</td></tr>
+                   <tr><td class=fielddesc>The name of the product 
offering.</td></tr>
+
+                   <tr class=alt><td>shortName</td></tr>
+                   <tr><td class=fielddesc>Shortname associated with a saving 
product. <br>
+                       An abbreviated version of the name, used in reports or 
menus where space is limited.
+                   </td></tr>
+
+                   <tr class=alt><td>description</td></tr>
+                   <tr><td class=fielddesc>A description of the product 
offering.</td></tr>
+
+                               <tr class=alt><td>currencyCode</td></tr>
+                   <tr><td class=fielddesc>Three letter ISO code representing 
currency.</td></tr>
+
+                   <tr class=alt><td>digitsAfterDecimal</td></tr>
+                   <tr><td class=fielddesc>Override the currency default value 
for digitsAfterDecimal.</td></tr>
+
+                   <tr class=alt><td>inMultiplesOf</td></tr>
+                   <tr><td class=fielddesc>Override the default value for 
rounding currency to multiples of provided value.</td></tr>
+
+                               <tr 
class=alt><td>nominalAnnualInterestRate</td></tr>
+                   <tr><td class=fielddesc>The default interest rate set when 
creating savings accounts of this type of product. e.g. <b>5</b>% Per year - It 
number here is always expressed as the Nominal APR.</td></tr>
+
+                               <tr 
class=alt><td>interestCompoundingPeriodType</td></tr>
+                   <tr><td class=fielddesc>The period at which interest rate 
is compounded. 1=Daily, 4=Monthly (at end of month)</td></tr>
+
+                   <tr class=alt><td>interestPostingPeriodType</td></tr>
+                   <tr><td class=fielddesc>The period at which interest rate 
is posted or credited to savings account. 4=Monthly (at end of month), 
5=Quarterly (at end of quarter, 31st Mar, 30th Jun, 30th Sep, 31st 
Dec)</td></tr>
+
+                   <tr class=alt><td>interestCalculationType</td></tr>
+                   <tr><td class=fielddesc>The interest calculation method 
used: 1=Daily Balance or 2=Average Daily Balance</td></tr>
+
+                               <tr 
class=alt><td>interestCalculationDaysInYearType</td></tr>
+                   <tr><td class=fielddesc>The setting for number of days in 
year to use: 360=360 Days, 365=365 Days</td></tr>
+
+                               <tr 
class=alt><td>minRequiredOpeningBalance</td></tr>
+                   <tr><td class=fielddesc><b>Optional</b>: If provided, sets 
the minimum deposit amount required to open a savings account e.g. 
<b>2,000</b></td></tr>
+
+                   <tr class=alt><td>lockinPeriodFrequency</td></tr>
+                   <tr><td class=fielddesc><b>Optional</b>: If provided, used 
along with <i>lockinPeriodFrequencyType</i> to indicate the length of time that 
the savings account is 'locked in' and withdrawals are not allowed. e.g. 
<b>6</b> Months</td></tr>
+
+                   <tr class=alt><td>lockinPeriodFrequencyType</td></tr>
+                   <tr><td class=fielddesc><b>Optional</b>: If provided, used 
along with <i>lockinPeriodFrequency</i> to indicate the length of time that the 
savings account is 'locked in' and withdrawals are not allowed. 0=Days, 
1=Weeks, 2=Months, 3=Years
+                   e.g. 6 <b>Months</b></td></tr>
+
+                   <tr class=alt><td>withdrawalFeeForTransfers</td></tr>
+                   <tr><td class=fielddesc><b>Optional</b>: Used along with 
<i>withdrawalFeeAmount</i> to indicate whether the withdrawal fee should be 
applied on the account for account transfers .</td></tr>
+
+                               <tr class=alt><td>accountingRule</td></tr>
+                   <tr>
+                                       <td class=fielddesc>Specifies if 
accounting is enabled for the particular
+                                       product and the type of the accounting 
rule to be used
+                                       <span>Example 
Values:</span>1=NONE,2=CASH_BASED</td>
+                               </tr>
+
+                               <tr class=alt><td>allowOverdraft</td></tr>
+                   <tr><td class=fielddesc><b>Optional</b>: If provided, 
depending on the value mark the savings account as overdraft account </td></tr>
+
+                               <tr class=alt><td>overdraftLimit</td></tr>
+                   <tr><td class=fielddesc><b>Optional</b>: If provided, sets 
the maximum allowed overdraft amount for a  savings account e.g. <b>5,000</b> 
else set the limit as zero</td></tr>
+
+                               <tr 
class=alt><td>minBalanceForInterestCalculation</td></tr>
+                   <tr><td class=fielddesc><b>Optional</b>: If provided, 
balance must be greater than provided value for calculation of interest  e.g. 
<b>5,000</b> </td></tr>
+
+                   <tr class=alt><td>enforceMinRequiredBalance</td></tr>
+                   <tr><td class=fielddesc><b>Optional</b>: If set to 
<span>true</span>, validates that the account balance does not
+                   fall below <span>minRequiredBalance</span> </td></tr>
+
+                               <tr class=alt><td>minRequiredBalance</td></tr>
+                   <tr><td class=fielddesc><b>Optional</b>: If provided, sets 
an indicator of the minimum required balance of the  savings account e.g. 
<b>5,000</b> else set the limit as zero. Note that 
<span>enforceMinRequiredBalance</span> determines if the minimum required 
balance is enforced</td></tr>
+
+                               <tr class=alt><td>withHoldTax</td></tr>
+                   <tr><td class=fielddesc><b>Optional</b>: If provided, sets 
an indicator for applying withhold tax on interest posting for savings account 
</td></tr>
+
+                               <tr class=alt><td>taxGroupId</td></tr>
+                   <tr><td class=fielddesc><b>Optional</b>: If withhold tax 
set as true, with hold tax will be applied as per the tax group provided 
</td></tr>
+
+
+               </table>
+           </div>
+       </div>
+       
+          <a id="self_savingsproducts_list" name="self_savingsproducts_list" 
class="old-syle-anchor">&nbsp;</a>
+    <div class="method-section">
+        <div class="method-description">
+            <h4>List Savings Products</h4>
+            <p>Example Requests:</p>
+            <div class=apiClick>self/savingsproducts?clientId=1</div>
+        </div>
+        <div class="method-example">
+            <code class="method-declaration">GET 
https://domainname/api/v1/self/savingsproducts?clientid={clientid}</code>
+            <code class="method-response">
+[
+  {
+    "id": 1,
+    "name": "Savings product",
+    "shortName": "sa1",
+    "description": "savings",
+    "currency": {
+      "code": "USD",
+      "name": "US Dollar",
+      "decimalPlaces": 2,
+      "displaySymbol": "$",
+      "nameCode": "currency.USD",
+      "displayLabel": "US Dollar ($)"
+    },
+    "nominalAnnualInterestRate": 5.000000,
+    "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"
+    },
+    "withdrawalFeeForTransfers": false,
+    "accountingRule": {
+      "id": 2,
+      "code": "accountingRuleType.cash",
+      "value": "CASH BASED"
+    }
+  }
+]                      </code>
+        </div>
+    </div>
+       
+         <a id="self_savingsproducts_retrieve" 
name="self_savingsproducts_retrieve" class="old-syle-anchor">&nbsp;</a>
+    <div class="method-section">
+        <div class="method-description">
+            <h4>Retrieve a Savings Product</h4>
+            <p>Example Requests: </p>
+            <div class=apiClick>self/savingsproducts/1?clientId=1</div>
+            <br><br>
+            <div 
class=apiClick>self/savingsproducts/1?fields=name,description&clientId=1</div>
+        </div>
+        <div class="method-example">
+                       <code class="method-declaration">GET 
https://DomainName/api/v1/self/savingsproducts/{productId}&clientId={clientId}</code>
+                       <code class="method-response">
+{
+  "id": 1,
+  "name": "savings product",
+  "shortName": "sa1",
+  "description": "savings",
+  "currency": {
+    "code": "USD",
+    "name": "US Dollar",
+    "decimalPlaces": 2,
+    "displaySymbol": "$",
+    "nameCode": "currency.USD",
+    "displayLabel": "US Dollar ($)"
+  },
+  "nominalAnnualInterestRate": 5.000000,
+  "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"
+  },
+  "withdrawalFeeForTransfers": false,
+  "accountingRule": {
+    "id": 2,
+    "code": "accountingRuleType.cash",
+    "value": "CASH BASED"
+  },
+  "accountingMappings": {
+    "savingsReferenceAccount": {
+      "id": 12,
+      "name": "savings ref",
+      "glCode": "20"
+    },
+    "incomeFromFeeAccount": {
+      "id": 16,
+      "name": "income from savings fee",
+      "glCode": "24"
+    },
+    "incomeFromPenaltyAccount": {
+      "id": 17,
+      "name": "income from sav penalites",
+      "glCode": "25"
+    },
+    "interestOnSavingsAccount": {
+      "id": 15,
+      "name": "interest on savings",
+      "glCode": "23"
+    },
+    "savingsControlAccount": {
+      "id": 13,
+      "name": "savings ref tool kit",
+      "glCode": "21"
+    },
+    "transfersInSuspenseAccount": {
+      "id": 14,
+      "name": "saving transfers",
+      "glCode": "22"
+    }
+  },
+  "paymentChannelToFundSourceMappings": [
+    {
+      "paymentType": {
+        "id": 10,
+        "name": "check"
+      },
+      "fundSourceAccount": {
+        "id": 12,
+        "name": "savings ref",
+        "glCode": "20"
+      }
+    }
+  ],
+  "feeToIncomeAccountMappings": [
+    {
+      "charge": {
+        "id": 11,
+        "name": "sav charge",
+        "active": false,
+        "penalty": false
+      },
+      "incomeAccount": {
+        "id": 16,
+        "name": "income from savings fee",
+        "glCode": "24"
+      }
+    }
+  ],
+  "penaltyToIncomeAccountMappings": [
+    {
+      "charge": {
+        "id": 12,
+        "name": "sav 2",
+        "active": false,
+        "penalty": true
+      },
+      "incomeAccount": {
+        "id": 17,
+        "name": "income from sav penalites",
+        "glCode": "25"
+      }
+    }
+  ],
+  "charges": []
+}
+                       </code>
+        </div>
+    </div>
+       
+       <a id="self_shareproducts_list" name="self_shareproducts_list" 
class="old-syle-anchor">&nbsp;</a>
+    <div class="method-section">
+        <div class="method-description">
+            <h4>List Share Products</h4>
+            <p>Example Requests:</p>
+            <div class=apiClick>self/products/share?clientId=1</div>
+        </div>
+        <div class="method-example">
+
+            <code class="method-declaration">GET 
https://DomainName/api/v1/self/products/share?clientId={clientId}</code>
+            <code class="method-response">
+
+{
+    "totalFilteredRecords": 2,
+    "pageItems": [
+        {
+            "id": 1,
+            "name": "Share P1",
+            "shortName": "shar",
+            "description": "Share",
+            "currency": {
+                "code": "USD",
+                "name": "US Dollar",
+                "decimalPlaces": 2,
+                "inMultiplesOf": 1,
+                "displaySymbol": "$",
+                "nameCode": "currency.USD",
+                "displayLabel": "US Dollar ($)"
+            },
+            "totalShares": 1000,
+            "totalSharesIssued": 450,
+            "unitPrice": 5,
+            "shareCapital": 2250,
+            "minimumShares": 2,
+            "nominalShares": 5,
+            "maximumShares": 8,
+            "allowDividendCalculationForInactiveClients": false,
+            "lockinPeriod": 1,
+            "lockPeriodTypeEnum": {
+                "id": 1,
+                "code": "shares.lockin.sharePeriodFrequencyType.weeks",
+                "value": "Weeks"
+            },
+            "minimumActivePeriod": 10,
+            "minimumActivePeriodForDividendsTypeEnum": {
+                "id": 0,
+                "code": "shares.minimumactive.sharePeriodFrequencyType.days",
+                "value": "Days"
+            },
+            "accountingRule": {
+                "id": 1,
+                "code": "accountingRuleType.none",
+                "value": "NONE"
+            }
+        },
+        {
+            "id": 2,
+            "name": "ShareP2",
+            "shortName": "comp",
+            "description": "Company shares",
+            "currency": {
+                "code": "USD",
+                "name": "US Dollar",
+                "decimalPlaces": 2,
+                "inMultiplesOf": 1,
+                "displaySymbol": "$",
+                "nameCode": "currency.USD",
+                "displayLabel": "US Dollar ($)"
+            },
+            "totalShares": 500,
+            "totalSharesIssued": 200,
+            "unitPrice": 2,
+            "shareCapital": 400,
+            "nominalShares": 5,
+            "allowDividendCalculationForInactiveClients": false,
+            "lockinPeriod": 1,
+            "lockPeriodTypeEnum": {
+                "id": 0,
+                "code": "shares.lockin.sharePeriodFrequencyType.days",
+                "value": "Days"
+            },
+            "minimumActivePeriod": 10,
+            "minimumActivePeriodForDividendsTypeEnum": {
+                "id": 0,
+                "code": "shares.minimumactive.sharePeriodFrequencyType.days",
+                "value": "Days"
+            },
+            "accountingRule": {
+                "id": 2,
+                "code": "accountingRuleType.cash",
+                "value": "CASH BASED"
+            }
+        }
+    ]
+}
+</code>
+       </div>
+</div>
+
+ <a id="self_shareproducts_retrieve" name="self_shareproducts_retrieve" 
class="old-syle-anchor">&nbsp;</a>
+    <div class="method-section">
+        <div class="method-description">
+            <h4>Retrieve a Share Product</h4>
+            <p>Example Requests: </p>
+            <div class=apiClick>self/products/share/2?clientId=1</div>
+            <br><br>
+            <div 
class=apiClick>self/products/share/2?clientId=1&template=true</div>
+        </div>
+        <div class="method-example">
+                       <code class="method-declaration">GET 
https://DomainName/api/v1/self/products/share/{productId}?clientId={clientId}</code>
+                       <code class="method-response">
+{
+    "id": 2,
+    "name": "ShareP2",
+    "shortName": "comp",
+    "description": "Company shares",
+    "currency": {
+        "code": "USD",
+        "name": "US Dollar",
+        "decimalPlaces": 2,
+        "inMultiplesOf": 1,
+        "displaySymbol": "$",
+        "nameCode": "currency.USD",
+        "displayLabel": "US Dollar ($)"
+    },
+    "totalShares": 500,
+    "totalSharesIssued": 200,
+    "unitPrice": 2,
+    "shareCapital": 400,
+    "nominalShares": 5,
+    "marketPrice": [
+        {
+            "id": 2,
+            "fromDate": "May 27, 2018",
+            "shareValue": 1
+        }
+    ],
+    "charges": [
+        {
+            "id": 1,
+            "name": "Activation",
+            "active": true,
+            "penalty": false,
+            "currency": {
+                "code": "USD",
+                "name": "US Dollar",
+                "decimalPlaces": 2,
+                "displaySymbol": "$",
+                "nameCode": "currency.USD",
+                "displayLabel": "US Dollar ($)"
+            },
+            "amount": 1,
+            "chargeTimeType": {
+                "id": 13,
+                "code": "chargeTimeType.activation",
+                "value": "Share Account Activate"
+            },
+            "chargeAppliesTo": {
+                "id": 4,
+                "code": "chargeAppliesTo.shares",
+                "value": "Shares"
+            },
+            "chargeCalculationType": {
+                "id": 1,
+                "code": "chargeCalculationType.flat",
+                "value": "Flat"
+            },
+            "chargePaymentMode": {
+                "id": 0,
+                "code": "chargepaymentmode.regular",
+                "value": "Regular"
+            }
+        }
+    ],
+    "allowDividendCalculationForInactiveClients": false,
+    "lockinPeriod": 1,
+    "lockPeriodTypeEnum": {
+        "id": 0,
+        "code": "shares.lockin.sharePeriodFrequencyType.days",
+        "value": "Days"
+    },
+    "minimumActivePeriod": 10,
+    "minimumActivePeriodForDividendsTypeEnum": {
+        "id": 0,
+        "code": "shares.minimumactive.sharePeriodFrequencyType.days",
+        "value": "Days"
+    },
+    "accountingRule": {
+        "id": 2,
+        "code": "accountingRuleType.cash",
+        "value": "CASH BASED"
+    },
+    "accountingMappings": {
+        "shareReferenceId": {
+            "id": 1,
+            "name": "GLAsset",
+            "glCode": "GL1"
+        },
+        "incomeFromFeeAccountId": {
+            "id": 4,
+            "name": "GLIncome",
+            "glCode": "GL4"
+        },
+        "shareEquityId": {
+            "id": 3,
+            "name": "GLEquity",
+            "glCode": "GL3"
+        },
+        "shareSuspenseId": {
+            "id": 2,
+            "name": "GL2Liabilities",
+            "glCode": "GL2"
+        }
+    }
+}
+                       </code>
+        </div>
+</div>
                        <!-- end of Customer Self Service APIs-->
         </div>
                <!-- main-content-wrapper -->
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/client/service/AppuserClientMapperReadService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/client/service/AppuserClientMapperReadService.java
index e69fad964..2090756ad 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/client/service/AppuserClientMapperReadService.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/client/service/AppuserClientMapperReadService.java
@@ -21,5 +21,7 @@
 public interface AppuserClientMapperReadService {
 
        public Boolean isClientMappedToUser(Long clientId, Long appUserId);
+       
+       public void validateAppuserClientsMapping(final Long clientId);
 
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/client/service/AppuserClientMapperReadServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/client/service/AppuserClientMapperReadServiceImpl.java
index 8711dfd78..408166e34 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/client/service/AppuserClientMapperReadServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/client/service/AppuserClientMapperReadServiceImpl.java
@@ -19,6 +19,9 @@
 package org.apache.fineract.portfolio.self.client.service;
 
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import 
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.apache.fineract.portfolio.client.exception.ClientNotFoundException;
+import org.apache.fineract.useradministration.domain.AppUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
@@ -28,10 +31,12 @@
                AppuserClientMapperReadService {
 
        private final JdbcTemplate jdbcTemplate;
+       private final PlatformSecurityContext context;
 
        @Autowired
-       public AppuserClientMapperReadServiceImpl(final RoutingDataSource 
dataSource) {
+       public AppuserClientMapperReadServiceImpl(final RoutingDataSource 
dataSource, final PlatformSecurityContext context) {
                this.jdbcTemplate = new JdbcTemplate(dataSource);
+               this.context = context;
        }
 
        @Override
@@ -42,5 +47,18 @@ public Boolean isClientMappedToUser(Long clientId, Long 
appUserId) {
                                                                + " from 
m_selfservice_user_client_mapping where client_id = ? and appuser_id = ?",
                                                new Object[] { clientId, 
appUserId }, Boolean.class);
        }
+       
+       @Override
+       public void validateAppuserClientsMapping(final Long clientId) {
+               AppUser user = this.context.authenticatedUser();
+               if (clientId != null) {
+                       final boolean mappedClientId = 
isClientMappedToUser(clientId, user.getId());
+                       if (!mappedClientId) {
+                               throw new ClientNotFoundException(clientId);
+                       }
+               } else
+                       throw new ClientNotFoundException(clientId);
+
+       }
 
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/products/api/SelfLoanProductsApiResource.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/products/api/SelfLoanProductsApiResource.java
new file mode 100644
index 000000000..dece2df8c
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/products/api/SelfLoanProductsApiResource.java
@@ -0,0 +1,77 @@
+/**
+ * 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.products.api;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
+import org.apache.fineract.portfolio.loanproduct.api.LoanProductsApiResource;
+import 
org.apache.fineract.portfolio.self.client.service.AppuserClientMapperReadService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+@Path("/self/loanproducts")
+@Component
+@Scope("singleton")
+public class SelfLoanProductsApiResource {
+
+       private final LoanProductsApiResource loanProductsApiResource;
+       private final AppuserClientMapperReadService 
appUserClientMapperReadService;
+
+       @Autowired
+       public SelfLoanProductsApiResource(final LoanProductsApiResource 
loanProductsApiResource,
+                       final AppuserClientMapperReadService 
appUserClientMapperReadService) {
+               this.loanProductsApiResource = loanProductsApiResource;
+               this.appUserClientMapperReadService = 
appUserClientMapperReadService;
+
+       }
+
+       @GET
+       @Consumes({ MediaType.APPLICATION_JSON })
+       @Produces({ MediaType.APPLICATION_JSON })
+       public String 
retrieveAllLoanProducts(@QueryParam(LoanApiConstants.clientIdParameterName) 
final Long clientId,
+                       @Context final UriInfo uriInfo) {
+
+               
this.appUserClientMapperReadService.validateAppuserClientsMapping(clientId);
+               return 
this.loanProductsApiResource.retrieveAllLoanProducts(uriInfo);
+
+       }
+
+       @GET
+       @Path("{productId}")
+       @Consumes({ MediaType.APPLICATION_JSON })
+       @Produces({ MediaType.APPLICATION_JSON })
+       public String 
retrieveLoanProductDetails(@QueryParam(LoanApiConstants.clientIdParameterName) 
final Long clientId,
+                       @PathParam(LoanApiConstants.productIdParameterName) 
final Long productId, @Context final UriInfo uriInfo) {
+
+               
this.appUserClientMapperReadService.validateAppuserClientsMapping(clientId);
+               return 
this.loanProductsApiResource.retrieveLoanProductDetails(productId, uriInfo);
+       }
+
+}
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/products/api/SelfSavingsProductsApiResource.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/products/api/SelfSavingsProductsApiResource.java
new file mode 100644
index 000000000..d3753637d
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/products/api/SelfSavingsProductsApiResource.java
@@ -0,0 +1,78 @@
+/**
+ * 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.products.api;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.fineract.portfolio.savings.SavingsApiConstants;
+import org.apache.fineract.portfolio.savings.api.SavingsProductsApiResource;
+import 
org.apache.fineract.portfolio.self.client.service.AppuserClientMapperReadService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+@Path("/self/savingsproducts")
+@Component
+@Scope("singleton")
+public class SelfSavingsProductsApiResource {
+
+       private final SavingsProductsApiResource savingsProductsApiResource;
+       private final AppuserClientMapperReadService 
appUserClientMapperReadService;
+
+       @Autowired
+       public SelfSavingsProductsApiResource(final SavingsProductsApiResource 
savingsProductsApiResource,
+                       final AppuserClientMapperReadService 
appUserClientMapperReadService) {
+               this.savingsProductsApiResource = savingsProductsApiResource;
+               this.appUserClientMapperReadService = 
appUserClientMapperReadService;
+
+       }
+
+       @GET
+       @Consumes({ MediaType.APPLICATION_JSON })
+       @Produces({ MediaType.APPLICATION_JSON })
+       public String 
retrieveAll(@QueryParam(SavingsApiConstants.clientIdParamName) final Long 
clientId,
+                       @Context final UriInfo uriInfo) {
+
+               
this.appUserClientMapperReadService.validateAppuserClientsMapping(clientId);
+               return this.savingsProductsApiResource.retrieveAll(uriInfo);
+
+       }
+
+       @GET
+       @Path("{productId}")
+       @Consumes({ MediaType.APPLICATION_JSON })
+       @Produces({ MediaType.APPLICATION_JSON })
+       public String 
retrieveOne(@PathParam(SavingsApiConstants.productIdParamName) final Long 
productId,
+                       @QueryParam(SavingsApiConstants.clientIdParamName) 
final Long clientId, @Context final UriInfo uriInfo) {
+
+               
this.appUserClientMapperReadService.validateAppuserClientsMapping(clientId);
+               return this.savingsProductsApiResource.retrieveOne(productId, 
uriInfo);
+
+       }
+
+}
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/products/api/SelfShareProductsApiResource.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/products/api/SelfShareProductsApiResource.java
new file mode 100644
index 000000000..97035d486
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/products/api/SelfShareProductsApiResource.java
@@ -0,0 +1,79 @@
+/**
+ * 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.products.api;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+
+import 
org.apache.fineract.portfolio.accounts.constants.ShareAccountApiConstants;
+import org.apache.fineract.portfolio.products.api.ProductsApiResource;
+import 
org.apache.fineract.portfolio.self.client.service.AppuserClientMapperReadService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+@Path("/self/products/share")
+@Component
+@Scope("singleton")
+public class SelfShareProductsApiResource {
+
+       private final ProductsApiResource productsApiResource;
+       private final AppuserClientMapperReadService 
appUserClientMapperReadService;
+
+       @Autowired
+       public SelfShareProductsApiResource(final ProductsApiResource 
productsApiResource,
+                       final AppuserClientMapperReadService 
appUserClientMapperReadService) {
+               this.productsApiResource = productsApiResource;
+               this.appUserClientMapperReadService = 
appUserClientMapperReadService;
+
+       }
+
+       @GET
+       @Path("{productId}")
+       @Consumes({ MediaType.APPLICATION_JSON })
+       @Produces({ MediaType.APPLICATION_JSON })
+       public String 
retrieveProduct(@QueryParam(ShareAccountApiConstants.clientid_paramname) final 
Long clientId,
+                       @PathParam("productId") final Long productId, 
@PathParam("type") final String productType,
+                       @Context final UriInfo uriInfo) {
+               
this.appUserClientMapperReadService.validateAppuserClientsMapping(clientId);
+               return this.productsApiResource.retrieveProduct(productId, 
ShareAccountApiConstants.shareEntityType, uriInfo);
+
+       }
+
+       @GET
+       @Consumes({ MediaType.APPLICATION_JSON })
+       @Produces({ MediaType.APPLICATION_JSON })
+       public String 
retrieveAllProducts(@QueryParam(ShareAccountApiConstants.clientid_paramname) 
final Long clientId,
+                       @QueryParam("offset") final Integer offset, 
@QueryParam("limit") final Integer limit,
+                       @Context final UriInfo uriInfo) {
+               
this.appUserClientMapperReadService.validateAppuserClientsMapping(clientId);
+               return 
this.productsApiResource.retrieveAllProducts(ShareAccountApiConstants.shareEntityType,
 offset, limit,
+                               uriInfo);
+
+       }
+
+}


 

----------------------------------------------------------------
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:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to