MIFOSX-250: interest calculation change for compounding with api docs updates.
This commit is contained in:
+291
-96
@@ -7496,11 +7496,17 @@ Content-Type: application/json
|
||||
<tr class=alt><td>digitsAfterDecimal</td></tr>
|
||||
<tr><td class=fielddesc>Override the currency default value for digitsAfterDecimal.</td></tr>
|
||||
|
||||
<tr class=alt><td>interestRate</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</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>interestRatePeriodFrequencyType</td></tr>
|
||||
<tr><td class=fielddesc>The default interest rate period type. 2=Per month, 3=Per year e.g. 5% <b>Per year</b></td></tr>
|
||||
<tr class=alt><td>interestCompoundingPeriodType</td></tr>
|
||||
<tr><td class=fielddesc>The period at which interest rate is compounded. 1=Daily, 2=Weekly (at end of week, sunday), 3=Every two weeks (at end of two weeks, sunday), 4=Monthly (at end of month), 5=Quarterly (at end of quarter, 31st Mar, 30th Jun, 30th Sep, 31st Dec), 6=Bi-Annually (30th June, 31st Dec), 7=Annually (31st Dec), 8=No Compounding - Simple Interest</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>
|
||||
@@ -7515,7 +7521,7 @@ Content-Type: application/json
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="savingsproducts_template" name="savingsproducts_template" class="old-syle-anchor"> </a>
|
||||
<a id="savingsproducts_template" name="savingsproducts_template" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Retrieve Savings Product Template</h4>
|
||||
@@ -7533,17 +7539,27 @@ Content-Type: application/json
|
||||
<code class="method-response">
|
||||
{
|
||||
"currency": {
|
||||
"code": "",
|
||||
"name": "",
|
||||
"decimalPlaces": 0,
|
||||
"displaySymbol": "",
|
||||
"nameCode": "",
|
||||
"displayLabel": " []"
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"displaySymbol": "$",
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"interestRatePeriodFrequencyType": {
|
||||
"id": 3,
|
||||
"code": "savings.interest.rate.periodFrequencyType.years",
|
||||
"value": "Per year"
|
||||
"interestCompoundingPeriodType": {
|
||||
"id": 1,
|
||||
"code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily",
|
||||
"value": "Daily"
|
||||
},
|
||||
"interestCalculationType": {
|
||||
"id": 1,
|
||||
"code": "savingsInterestCalculationType.dailybalance",
|
||||
"value": "Daily Balance"
|
||||
},
|
||||
"interestCalculationDaysInYearType": {
|
||||
"id": 365,
|
||||
"code": "savingsInterestCalculationDaysInYearType.days365",
|
||||
"value": "365 Days"
|
||||
},
|
||||
"currencyOptions": [
|
||||
{
|
||||
@@ -7555,37 +7571,91 @@ Content-Type: application/json
|
||||
"displayLabel": "US Dollar ($)"
|
||||
}
|
||||
],
|
||||
"interestRatePeriodFrequencyTypeOptions": [
|
||||
"interestCompoundingPeriodTypeOptions": [
|
||||
{
|
||||
"id": 1,
|
||||
"code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily",
|
||||
"value": "Daily"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"code": "savings.interest.rate.periodFrequencyType.months",
|
||||
"value": "Per month"
|
||||
"code": "savings.interest.period.savingsCompoundingInterestPeriodType.weekly",
|
||||
"value": "Weekly"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"code": "savings.interest.rate.periodFrequencyType.years",
|
||||
"value": "Per year"
|
||||
"code": "savings.interest.period.savingsCompoundingInterestPeriodType.biweekly",
|
||||
"value": "Bi-Weekly"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"code": "savings.interest.period.savingsCompoundingInterestPeriodType.nocompounding",
|
||||
"value": "No Compounding - Simple Interest"
|
||||
}
|
||||
],
|
||||
"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.periodFrequencyType.days",
|
||||
"code": "savings.lockin.savingsPeriodFrequencyType.days",
|
||||
"value": "Days"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"code": "savings.lockin.periodFrequencyType.weeks",
|
||||
"code": "savings.lockin.savingsPeriodFrequencyType.weeks",
|
||||
"value": "Weeks"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"code": "savings.lockin.periodFrequencyType.months",
|
||||
"code": "savings.lockin.savingsPeriodFrequencyType.months",
|
||||
"value": "Months"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"code": "savings.lockin.periodFrequencyType.years",
|
||||
"code": "savings.lockin.savingsPeriodFrequencyType.years",
|
||||
"value": "Years"
|
||||
}
|
||||
]
|
||||
@@ -7600,7 +7670,10 @@ Content-Type: application/json
|
||||
<h4>Create a Savings Product</h4>
|
||||
<table class=matrixHeading>
|
||||
<tr class="matrixHeadingBG"><td><div class="mifosXHeading2">Mandatory Fields</div></td></tr>
|
||||
<tr class=alt><td>name, description, currencyCode, digitsAfterDecimal, interestRate, interestRatePeriodFrequencyType</tr>
|
||||
<tr class=alt>
|
||||
<td>name, description, currencyCode, digitsAfterDecimal, nominalAnnualInterestRate,
|
||||
interestCompoundingPeriodType, interestCalculationType, interestCalculationDaysInYearType</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
<table class=matrixHeading>
|
||||
@@ -7614,13 +7687,15 @@ Content-Type: application/json
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"name": "individual savings",
|
||||
"description": "An savings product offering for individuals.",
|
||||
"name": "Passbook Savings",
|
||||
"description": "Daily compounding using Daily Balance, 5% per year, 365 days in year",
|
||||
"currencyCode": "USD",
|
||||
"digitsAfterDecimal": 2,
|
||||
"locale": "en",
|
||||
"interestRate": "5.65",
|
||||
"interestRatePeriodFrequencyType": 2
|
||||
"nominalAnnualInterestRate": "5.0",
|
||||
"interestCompoundingPeriodType": 1,
|
||||
"interestCalculationType": 1,
|
||||
"interestCalculationDaysInYearType": "365"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
@@ -7647,8 +7722,8 @@ Request Body:
|
||||
<code class="method-response">
|
||||
{
|
||||
"id": 1,
|
||||
"name": "individual savings",
|
||||
"description": "An savings product offering for individuals. (updated)",
|
||||
"name": "Passbook Savings",
|
||||
"description": "Daily compounding using Daily Balance, 5% per year, 365 days in year",
|
||||
"currency": {
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
@@ -7657,13 +7732,23 @@ Request Body:
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"interestRate": 5.73,
|
||||
"interestRatePeriodFrequencyType": {
|
||||
"id": 2,
|
||||
"code": "savings.interest.rate.periodFrequencyType.months",
|
||||
"value": "Per month"
|
||||
"nominalAnnualInterestRate": 5,
|
||||
"interestCompoundingPeriodType": {
|
||||
"id": 1,
|
||||
"code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily",
|
||||
"value": "Daily"
|
||||
},
|
||||
"interestCalculationType": {
|
||||
"id": 1,
|
||||
"code": "savingsInterestCalculationType.dailybalance",
|
||||
"value": "Daily Balance"
|
||||
},
|
||||
"interestCalculationDaysInYearType": {
|
||||
"id": 365,
|
||||
"code": "savingsInterestCalculationDaysInYearType.days365",
|
||||
"value": "365 Days"
|
||||
}
|
||||
}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
@@ -7679,7 +7764,7 @@ Request Body:
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"description": "An savings product offering for individuals. (updated)",
|
||||
"description": "Passbook Savings Lite.",
|
||||
"locale": "en",
|
||||
"interestRate": "5.73"
|
||||
}
|
||||
@@ -7688,7 +7773,7 @@ Request Body:
|
||||
{
|
||||
"resourceId": 1,
|
||||
"changes": {
|
||||
"description": "An savings product offering for individuals. (updated)",
|
||||
"description": "Passbook Savings Lite.",
|
||||
"interestRate": 5.73,
|
||||
"locale": "en"
|
||||
}
|
||||
@@ -7731,32 +7816,35 @@ Content-Type: application/json
|
||||
<code class="method-declaration">GET https://Domain Name/api/v1/savingsproducts</code>
|
||||
<code class="method-response">
|
||||
[
|
||||
{
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Passbook Savings",
|
||||
"description": "Daily compounding using Daily Balance, 5% per year, 365 days in year",
|
||||
"currency": {
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"displaySymbol": "$",
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"nominalAnnualInterestRate": 5,
|
||||
"interestCompoundingPeriodType": {
|
||||
"id": 1,
|
||||
"name": "individual savings",
|
||||
"description": "An savings product offering for individuals. (updated)",
|
||||
"currency": {
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
"decimalPlaces": 2,
|
||||
"displaySymbol": "$",
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"interestRate": 9.85,
|
||||
"interestRatePeriodFrequencyType": {
|
||||
"id": 3,
|
||||
"code": "savings.interest.rate.periodFrequencyType.years",
|
||||
"value": "Per year"
|
||||
},
|
||||
"minRequiredOpeningBalance": 1000,
|
||||
"lockinPeriodFrequency": 3,
|
||||
"lockinPeriodFrequencyType": {
|
||||
"id": 2,
|
||||
"code": "savings.interest.rate.periodFrequencyType.months",
|
||||
"value": "Per month"
|
||||
}
|
||||
"code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily",
|
||||
"value": "Daily"
|
||||
},
|
||||
"interestCalculationType": {
|
||||
"id": 1,
|
||||
"code": "savingsInterestCalculationType.dailybalance",
|
||||
"value": "Daily Balance"
|
||||
},
|
||||
"interestCalculationDaysInYearType": {
|
||||
"id": 365,
|
||||
"code": "savingsInterestCalculationDaysInYearType.days365",
|
||||
"value": "365 Days"
|
||||
}
|
||||
}
|
||||
]
|
||||
</code>
|
||||
</div>
|
||||
@@ -7793,11 +7881,17 @@ Content-Type: application/json
|
||||
<tr class=alt><td>activationDate</td></tr>
|
||||
<tr><td class=fielddesc>If <b>active</b> is true the <i>activationDate</i> must be provided. If the savings account has an entry for <i>minRequiredOpeningBalance</i> then a deposit for that amount with <i>activationDate</i> as the date is automatically entered.</td></tr>
|
||||
|
||||
<tr class=alt><td>interestRate</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</td></tr>
|
||||
<tr class=alt><td>nominalAnnualInterestRate</td></tr>
|
||||
<tr><td class=fielddesc>The interest rate set for savings account e.g. <b>5</b>% Per year - It is always expressed as the Nominal APR.</td></tr>
|
||||
|
||||
<tr class=alt><td>interestRatePeriodFrequencyType</td></tr>
|
||||
<tr><td class=fielddesc>The default interest rate period type. 2=Per month, 3=Per year e.g. 5% <b>Per year</b></td></tr>
|
||||
<tr class=alt><td>interestCompoundingPeriodType</td></tr>
|
||||
<tr><td class=fielddesc>The period at which interest rate is compounded. 1=Daily, 2=Weekly (at end of week, sunday), 3=Every two weeks (at end of two weeks, sunday), 4=Monthly (at end of month), 5=Quarterly (at end of quarter, 31st Mar, 30th Jun, 30th Sep, 31st Dec), 6=Bi-Annually (30th June, 31st Dec), 7=Annually (31st Dec), 8=No Compounding - Simple Interest</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>
|
||||
@@ -7856,9 +7950,9 @@ Content-Type: application/json
|
||||
<code class="method-response">
|
||||
{
|
||||
"clientId": 1,
|
||||
"clientName": "Client A AB",
|
||||
"savingsProductId": 1,
|
||||
"savingsProductName": "First",
|
||||
"clientName": "John Doe",
|
||||
"savingsProductId": 3,
|
||||
"savingsProductName": "Passbook Savings",
|
||||
"currency": {
|
||||
"code": "USD",
|
||||
"name": "US Dollar",
|
||||
@@ -7867,56 +7961,121 @@ Content-Type: application/json
|
||||
"nameCode": "currency.USD",
|
||||
"displayLabel": "US Dollar ($)"
|
||||
},
|
||||
"interestRate": 12,
|
||||
"interestRatePeriodFrequencyType": {
|
||||
"id": 3,
|
||||
"code": "savings.interest.rate.periodFrequencyType.years",
|
||||
"value": "Per year"
|
||||
"nominalAnnualInterestRate": 5,
|
||||
"interestCompoundingPeriodType": {
|
||||
"id": 1,
|
||||
"code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily",
|
||||
"value": "Daily"
|
||||
},
|
||||
"minRequiredOpeningBalance": 1000,
|
||||
"lockinPeriodFrequency": 3,
|
||||
"lockinPeriodFrequencyType": {
|
||||
"id": 2,
|
||||
"code": "savings.interest.rate.periodFrequencyType.months",
|
||||
"value": "Per month"
|
||||
"interestCalculationType": {
|
||||
"id": 1,
|
||||
"code": "savingsInterestCalculationType.dailybalance",
|
||||
"value": "Daily Balance"
|
||||
},
|
||||
"interestCalculationDaysInYearType": {
|
||||
"id": 365,
|
||||
"code": "savingsInterestCalculationDaysInYearType.days365",
|
||||
"value": "365 Days"
|
||||
},
|
||||
"productOptions": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "First"
|
||||
}
|
||||
],
|
||||
"interestRatePeriodFrequencyTypeOptions": [
|
||||
"name": "01-Compounding Daily"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"code": "savings.interest.rate.periodFrequencyType.months",
|
||||
"value": "Per month"
|
||||
"name": "02-Compounding Monthly"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"code": "savings.interest.rate.periodFrequencyType.years",
|
||||
"value": "Per year"
|
||||
"name": "Passbook Savings"
|
||||
}
|
||||
],
|
||||
"interestCompoundingPeriodTypeOptions": [
|
||||
{
|
||||
"id": 1,
|
||||
"code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily",
|
||||
"value": "Daily"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"code": "savings.interest.period.savingsCompoundingInterestPeriodType.weekly",
|
||||
"value": "Weekly"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"code": "savings.interest.period.savingsCompoundingInterestPeriodType.biweekly",
|
||||
"value": "Bi-Weekly"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"code": "savings.interest.period.savingsCompoundingInterestPeriodType.nocompounding",
|
||||
"value": "No Compounding - Simple Interest"
|
||||
}
|
||||
],
|
||||
"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.periodFrequencyType.days",
|
||||
"code": "savings.lockin.savingsPeriodFrequencyType.days",
|
||||
"value": "Days"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"code": "savings.lockin.periodFrequencyType.weeks",
|
||||
"code": "savings.lockin.savingsPeriodFrequencyType.weeks",
|
||||
"value": "Weeks"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"code": "savings.lockin.periodFrequencyType.months",
|
||||
"code": "savings.lockin.savingsPeriodFrequencyType.months",
|
||||
"value": "Months"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"code": "savings.lockin.periodFrequencyType.years",
|
||||
"code": "savings.lockin.savingsPeriodFrequencyType.years",
|
||||
"value": "Years"
|
||||
}
|
||||
]
|
||||
@@ -7932,7 +8091,8 @@ Content-Type: application/json
|
||||
<br/>
|
||||
<table class=matrixHeading>
|
||||
<tr class="matrixHeadingBG"><td><div class="mifosXHeading2">Mandatory Fields</div></td></tr>
|
||||
<tr class=alt><td>clientId or groupId, productId, accountNo, externalId, active, (activationDate if active is true)</td></tr>
|
||||
<tr class=alt><td>clientId or groupId, productId, accountNo, externalId,
|
||||
active, (activationDate if active is true)</td></tr>
|
||||
</table>
|
||||
<br/>
|
||||
<table class=matrixHeading>
|
||||
@@ -7942,7 +8102,7 @@ Content-Type: application/json
|
||||
<br/>
|
||||
<table class=matrixHeading>
|
||||
<tr class="matrixHeadingBG"><td><div class="mifosXHeading2">Inherited from Product (if not provided)</div></td></tr>
|
||||
<tr class=alt><td>interestRate, interestRatePeriodFrequencyType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType</td></tr>
|
||||
<tr class=alt><td>nominalAnnualInterestRate, interestCompoundingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
@@ -8028,6 +8188,33 @@ Request Body:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="savingsaccounts_calculate_interest" name="savingsaccounts_calculate_interest" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h2>Calculate Interest on Savings Account</h2>
|
||||
<p>
|
||||
Calculates interest earned on a savings account based on todays date. It does not attempt to <b>post or credit</b> the interest on the account. That is responsibility of another API that will be called by overnight process.
|
||||
</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/savingsaccounts/{savingsId}?command=calculateInterest</code>
|
||||
<code class="method-request">POST savingsaccount/1?command=calculateInterest
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"officeId": 1,
|
||||
"clientId": 1,
|
||||
"savingsId": 1,
|
||||
"resourceId": 1
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="savingsaccounts_list" name="savingsaccounts_list" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
@@ -12290,6 +12477,14 @@ GET https://DomainName/api/v1/search?query=000000111
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>savingsaccounts/{accountId}?command=calculateInterest</td>
|
||||
<td><a href="#savingsaccounts_calculate_interest">Calculate Interest on a Savings Account</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td><a href="#savingsaccounts_transactions">Savings Transactions</a></td>
|
||||
<td>savingsaccounts/{accountId}/transactions?command=deposit</td>
|
||||
<td><a href="#savingsaccounts_deposit">Make a Deposit</a></td>
|
||||
@@ -12297,7 +12492,7 @@ GET https://DomainName/api/v1/search?query=000000111
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>savingsaccounts/{accountId}/transactions?command=withdrawal</td>
|
||||
<td><a href="#savingsaccounts_withdrawal">Make a Withdrawal</a></td>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
ALTER TABLE `m_savings_product`
|
||||
DROP COLUMN `nominal_interest_rate_period_frequency_enum`,
|
||||
CHANGE COLUMN `nominal_interest_rate_per_period` `nominal_annual_interest_rate` DECIMAL(19,6) NOT NULL,
|
||||
CHANGE COLUMN `interest_period_enum` `interest_compounding_period_enum` SMALLINT(5) NOT NULL;
|
||||
|
||||
|
||||
ALTER TABLE `m_savings_account`
|
||||
DROP COLUMN `annual_nominal_interest_rate`,
|
||||
DROP COLUMN `nominal_interest_rate_period_frequency_enum`,
|
||||
CHANGE COLUMN `nominal_interest_rate_per_period` `nominal_annual_interest_rate` DECIMAL(19,6) NOT NULL,
|
||||
CHANGE COLUMN `interest_period_enum` `interest_compounding_period_enum` SMALLINT(5) NOT NULL;
|
||||
+1
-5
@@ -13,7 +13,6 @@ import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.commands.data.CommandSourceData;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
@@ -23,11 +22,9 @@ import org.springframework.stereotype.Service;
|
||||
public class PortfolioCommandsReadPlatformServiceImpl implements PortfolioCommandsReadPlatformService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final PlatformSecurityContext context;
|
||||
|
||||
@Autowired
|
||||
public PortfolioCommandsReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) {
|
||||
this.context = context;
|
||||
public PortfolioCommandsReadPlatformServiceImpl(final TenantAwareRoutingDataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
@@ -53,7 +50,6 @@ public class PortfolioCommandsReadPlatformServiceImpl implements PortfolioComman
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CommandSourceData retrieveById(final Long id) {
|
||||
|
||||
|
||||
+5
-8
@@ -140,8 +140,7 @@ public class SavingsAccountsApiResource {
|
||||
|
||||
Collection<SavingsAccountTransactionData> transactions = null;
|
||||
Collection<SavingsProductData> productOptions = null;
|
||||
Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
Collection<EnumOptionData> interestPeriodTypeOptions = null;
|
||||
Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
||||
Collection<EnumOptionData> interestCalculationTypeOptions = null;
|
||||
Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||
Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
@@ -166,15 +165,13 @@ public class SavingsAccountsApiResource {
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
if (settings.isTemplate()) {
|
||||
productOptions = this.savingsProductReadPlatformService.retrieveAllForLookup();
|
||||
interestRatePeriodFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveInterestRatePeriodFrequencyTypeOptions();
|
||||
interestPeriodTypeOptions = this.dropdownReadPlatformService.retrieveInterestPeriodTypeOptions();
|
||||
interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService.retrieveCompoundingInterestPeriodTypeOptions();
|
||||
interestCalculationTypeOptions = this.dropdownReadPlatformService.retrieveInterestCalculationTypeOptions();
|
||||
lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveLockinPeriodFrequencyTypeOptions();
|
||||
}
|
||||
|
||||
return SavingsAccountData.withTemplateOptions(savingsAccount, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
interestPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions, transactions);
|
||||
return SavingsAccountData.withTemplateOptions(savingsAccount, productOptions, interestCompoundingPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@@ -195,7 +192,7 @@ public class SavingsAccountsApiResource {
|
||||
@Path("{accountId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String activate(@PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam,
|
||||
public String handleCommands(@PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam,
|
||||
final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||
|
||||
+15
-17
@@ -31,9 +31,9 @@ public class SavingsApiConstants {
|
||||
public static final String descriptionParamName = "description";
|
||||
public static final String currencyCodeParamName = "currencyCode";
|
||||
public static final String digitsAfterDecimalParamName = "digitsAfterDecimal";
|
||||
public static final String interestRateParamName = "interestRate";
|
||||
public static final String interestRatePeriodFrequencyTypeParamName = "interestRatePeriodFrequencyType";
|
||||
public static final String interestPeriodTypeParamName = "interestPeriodType";
|
||||
public static final String nominalAnnualInterestRateParamName = "nominalAnnualInterestRate";
|
||||
|
||||
public static final String interestCompoundingPeriodTypeParamName = "interestCompoundingPeriodType";
|
||||
public static final String interestCalculationTypeParamName = "interestCalculationType";
|
||||
public static final String interestCalculationDaysInYearTypeParamName = "interestCalculationDaysInYearType";
|
||||
public static final String minRequiredOpeningBalanceParamName = "minRequiredOpeningBalance";
|
||||
@@ -45,10 +45,9 @@ public class SavingsApiConstants {
|
||||
public static final String transactionAmountParamName = "transactionAmount";
|
||||
|
||||
public static final Set<String> SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
nameParamName, descriptionParamName, currencyCodeParamName, digitsAfterDecimalParamName, interestRateParamName,
|
||||
interestRatePeriodFrequencyTypeParamName, interestPeriodTypeParamName, interestCalculationTypeParamName,
|
||||
interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName,
|
||||
lockinPeriodFrequencyTypeParamName));
|
||||
nameParamName, descriptionParamName, currencyCodeParamName, digitsAfterDecimalParamName, nominalAnnualInterestRateParamName,
|
||||
interestCompoundingPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName,
|
||||
minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName));
|
||||
|
||||
/**
|
||||
* These parameters will match the class level parameters of
|
||||
@@ -56,17 +55,16 @@ public class SavingsApiConstants {
|
||||
* parameters to match those of request parameters.
|
||||
*/
|
||||
public static final Set<String> SAVINGS_PRODUCT_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName,
|
||||
nameParamName, descriptionParamName, "currency", digitsAfterDecimalParamName, interestRateParamName,
|
||||
interestRatePeriodFrequencyTypeParamName, interestPeriodTypeParamName, interestCalculationTypeParamName,
|
||||
interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName,
|
||||
lockinPeriodFrequencyTypeParamName, "currencyOptions", "interestRatePeriodFrequencyTypeOptions",
|
||||
"lockinPeriodFrequencyTypeOptions"));
|
||||
nameParamName, descriptionParamName, "currency", digitsAfterDecimalParamName, nominalAnnualInterestRateParamName,
|
||||
interestCompoundingPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName,
|
||||
minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName, "currencyOptions",
|
||||
"interestRatePeriodFrequencyTypeOptions", "lockinPeriodFrequencyTypeOptions"));
|
||||
|
||||
public static final Set<String> SAVINGS_ACCOUNT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
dateFormatParamName, accountNoParamName, externalIdParamName, clientIdParamName, groupIdParamName, productIdParamName,
|
||||
activeParamName, activationDateParamName, interestRateParamName, interestRatePeriodFrequencyTypeParamName,
|
||||
interestPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName,
|
||||
minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName));
|
||||
activeParamName, activationDateParamName, nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName,
|
||||
interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName,
|
||||
lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName));
|
||||
|
||||
/**
|
||||
* These parameters will match the class level parameters of
|
||||
@@ -75,8 +73,8 @@ public class SavingsApiConstants {
|
||||
*/
|
||||
public static final Set<String> SAVINGS_ACCOUNT_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName,
|
||||
accountNoParamName, externalIdParamName, statusParamName, activationDateParamName, clientIdParamName, "clientName",
|
||||
groupIdParamName, "groupName", "savingsProductId", "savingsProductName", "currency", interestRateParamName,
|
||||
interestRatePeriodFrequencyTypeParamName, "annualInterestRate", interestPeriodTypeParamName, interestCalculationTypeParamName,
|
||||
groupIdParamName, "groupName", "savingsProductId", "savingsProductName", "currency", nominalAnnualInterestRateParamName,
|
||||
interestCompoundingPeriodTypeParamName, interestCalculationTypeParamName,
|
||||
interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName,
|
||||
lockinPeriodFrequencyTypeParamName, "summary", "transactions", "productOptions", "interestRatePeriodFrequencyTypeOptions",
|
||||
"lockinPeriodFrequencyTypeOptions"));
|
||||
|
||||
+16
-17
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.savings.api;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
@@ -31,10 +32,9 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsDropdownReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsProductReadPlatformService;
|
||||
@@ -146,22 +146,23 @@ public class SavingsProductsApiResource {
|
||||
|
||||
private SavingsProductData handleTemplateRelatedData(final SavingsProductData savingsProduct) {
|
||||
|
||||
final EnumOptionData interestRatePeriodFrequencyType = SavingsEnumerations
|
||||
.interestRatePeriodFrequencyType(SavingsPeriodFrequencyType.YEARS);
|
||||
|
||||
final EnumOptionData interestPeriodType = SavingsEnumerations.interestPeriodType(SavingsInterestPeriodType.MONTHLY);
|
||||
final EnumOptionData interestPeriodType = SavingsEnumerations
|
||||
.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.DAILY);
|
||||
|
||||
final EnumOptionData interestCalculationType = SavingsEnumerations
|
||||
.interestCalculationType(SavingsInterestCalculationType.AVERAGE_DAILY_BALANCE);
|
||||
.interestCalculationType(SavingsInterestCalculationType.DAILY_BALANCE);
|
||||
|
||||
final EnumOptionData interestCalculationDaysInYearType = SavingsEnumerations
|
||||
.interestCalculationDaysInYearType(SavingsInterestCalculationDaysInYearType.DAYS_365);
|
||||
|
||||
CurrencyData currency = CurrencyData.blank();
|
||||
final Collection<CurrencyData> currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies();
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveInterestRatePeriodFrequencyTypeOptions();
|
||||
if (currencyOptions.size() == 1) {
|
||||
currency = new ArrayList<CurrencyData>(currencyOptions).get(0);
|
||||
}
|
||||
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions = this.dropdownReadPlatformService.retrieveInterestPeriodTypeOptions();
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveCompoundingInterestPeriodTypeOptions();
|
||||
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveInterestCalculationTypeOptions();
|
||||
@@ -174,14 +175,12 @@ public class SavingsProductsApiResource {
|
||||
|
||||
SavingsProductData savingsProductToReturn = null;
|
||||
if (savingsProduct != null) {
|
||||
savingsProductToReturn = SavingsProductData.withTemplate(savingsProduct, currencyOptions,
|
||||
interestRatePeriodFrequencyTypeOptions, interestPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
savingsProductToReturn = SavingsProductData.withTemplate(savingsProduct, currencyOptions, interestPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
} else {
|
||||
savingsProductToReturn = SavingsProductData.template(CurrencyData.blank(), interestRatePeriodFrequencyType, interestPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, currencyOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
interestPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
savingsProductToReturn = SavingsProductData.template(currency, interestPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
return savingsProductToReturn;
|
||||
|
||||
+30
-42
@@ -30,10 +30,8 @@ public class SavingsAccountData {
|
||||
private final Long savingsProductId;
|
||||
private final String savingsProductName;
|
||||
private final CurrencyData currency;
|
||||
private final BigDecimal interestRate;
|
||||
private final EnumOptionData interestRatePeriodFrequencyType;
|
||||
private final BigDecimal annualInterestRate;
|
||||
private final EnumOptionData interestPeriodType;
|
||||
private final BigDecimal nominalAnnualInterestRate;
|
||||
private final EnumOptionData interestCompoundingPeriodType;
|
||||
private final EnumOptionData interestCalculationType;
|
||||
private final EnumOptionData interestCalculationDaysInYearType;
|
||||
private final BigDecimal minRequiredOpeningBalance;
|
||||
@@ -46,8 +44,7 @@ public class SavingsAccountData {
|
||||
|
||||
// template
|
||||
private final Collection<SavingsProductData> productOptions;
|
||||
private final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions;
|
||||
private final Collection<EnumOptionData> interestPeriodTypeOptions;
|
||||
private final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions;
|
||||
private final Collection<EnumOptionData> interestCalculationTypeOptions;
|
||||
private final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions;
|
||||
private final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
|
||||
@@ -55,39 +52,37 @@ public class SavingsAccountData {
|
||||
public static SavingsAccountData instance(final Long id, final String accountNo, final String externalId,
|
||||
final SavingsAccountStatusEnumData status, final LocalDate activationDate, final Long groupId, final String groupName,
|
||||
final Long clientId, final String clientName, final Long productId, final String productName, final CurrencyData currency,
|
||||
final BigDecimal interestRate, final EnumOptionData interestRatePeriodFrequencyType, final BigDecimal annualInterestRate,
|
||||
final EnumOptionData interestPeriodType, final EnumOptionData interestCalculationType,
|
||||
final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType, final SavingsAccountSummaryData summary) {
|
||||
final BigDecimal interestRate, final EnumOptionData interestCompoundingPeriodType,
|
||||
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
|
||||
final EnumOptionData lockinPeriodFrequencyType, final SavingsAccountSummaryData summary) {
|
||||
|
||||
final Collection<SavingsProductData> productOptions = null;
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||
|
||||
return new SavingsAccountData(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName,
|
||||
productId, productName, currency, interestRate, interestRatePeriodFrequencyType, annualInterestRate, interestPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, summary, productOptions, interestRatePeriodFrequencyTypeOptions, interestPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
|
||||
productId, productName, currency, interestRate, interestCompoundingPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, summary,
|
||||
productOptions, interestCompoundingPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
public static SavingsAccountData withTemplateOptions(final SavingsAccountData account,
|
||||
final Collection<SavingsProductData> productOptions, final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions,
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions, final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final Collection<SavingsProductData> productOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<SavingsAccountTransactionData> transactions) {
|
||||
|
||||
return new SavingsAccountData(account.id, account.accountNo, account.externalId, account.status, account.activationDate,
|
||||
account.groupId, account.groupName, account.clientId, account.clientName, account.savingsProductId,
|
||||
account.savingsProductName, account.currency, account.interestRate, account.interestRatePeriodFrequencyType,
|
||||
account.annualInterestRate, account.interestPeriodType, account.interestCalculationType,
|
||||
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
|
||||
account.lockinPeriodFrequencyType, account.summary, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
interestPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
account.savingsProductName, account.currency, account.nominalAnnualInterestRate, account.interestCompoundingPeriodType,
|
||||
account.interestCalculationType, account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance,
|
||||
account.lockinPeriodFrequency, account.lockinPeriodFrequencyType, account.summary, productOptions,
|
||||
interestCompoundingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
@@ -102,9 +97,7 @@ public class SavingsAccountData {
|
||||
final Long productId = null;
|
||||
final String productName = null;
|
||||
final CurrencyData currency = null;
|
||||
final BigDecimal interestRate = null;
|
||||
final EnumOptionData interestRatePeriodFrequencyType = null;
|
||||
final BigDecimal annualInterestRate = null;
|
||||
final BigDecimal nominalAnnualInterestRate = null;
|
||||
final EnumOptionData interestPeriodType = null;
|
||||
final EnumOptionData interestCalculationType = null;
|
||||
final EnumOptionData interestCalculationDaysInYearType = null;
|
||||
@@ -114,29 +107,27 @@ public class SavingsAccountData {
|
||||
final SavingsAccountSummaryData summary = null;
|
||||
final Collection<SavingsProductData> productOptions = null;
|
||||
final Collection<CurrencyData> currencyOptions = null;
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||
|
||||
return new SavingsAccountData(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName,
|
||||
productId, productName, currency, interestRate, interestRatePeriodFrequencyType, annualInterestRate, interestPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, summary, productOptions, interestRatePeriodFrequencyTypeOptions, interestPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
|
||||
productId, productName, currency, nominalAnnualInterestRate, interestPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, summary,
|
||||
productOptions, interestCompoundingPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
private SavingsAccountData(final Long id, final String accountNo, final String externalId, final SavingsAccountStatusEnumData status,
|
||||
final LocalDate activationDate, final Long groupId, final String groupName, final Long clientId, final String clientName,
|
||||
final Long productId, final String productName, final CurrencyData currency, final BigDecimal interestRate,
|
||||
final EnumOptionData interestRatePeriodFrequencyType, final BigDecimal annualInterestRate,
|
||||
final Long productId, final String productName, final CurrencyData currency, final BigDecimal nominalAnnualInterestRate,
|
||||
final EnumOptionData interestPeriodType, final EnumOptionData interestCalculationType,
|
||||
final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType, final SavingsAccountSummaryData summary,
|
||||
final Collection<SavingsProductData> productOptions, final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions,
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions, final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final Collection<SavingsProductData> productOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<SavingsAccountTransactionData> transactions) {
|
||||
this.id = id;
|
||||
@@ -151,10 +142,8 @@ public class SavingsAccountData {
|
||||
this.savingsProductId = productId;
|
||||
this.savingsProductName = productName;
|
||||
this.currency = currency;
|
||||
this.interestRate = interestRate;
|
||||
this.interestRatePeriodFrequencyType = interestRatePeriodFrequencyType;
|
||||
this.annualInterestRate = annualInterestRate;
|
||||
this.interestPeriodType = interestPeriodType;
|
||||
this.nominalAnnualInterestRate = nominalAnnualInterestRate;
|
||||
this.interestCompoundingPeriodType = interestPeriodType;
|
||||
this.interestCalculationType = interestCalculationType;
|
||||
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType;
|
||||
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
|
||||
@@ -163,8 +152,7 @@ public class SavingsAccountData {
|
||||
this.summary = summary;
|
||||
|
||||
this.productOptions = productOptions;
|
||||
this.interestRatePeriodFrequencyTypeOptions = interestRatePeriodFrequencyTypeOptions;
|
||||
this.interestPeriodTypeOptions = interestPeriodTypeOptions;
|
||||
this.interestCompoundingPeriodTypeOptions = interestCompoundingPeriodTypeOptions;
|
||||
this.interestCalculationTypeOptions = interestCalculationTypeOptions;
|
||||
this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions;
|
||||
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
|
||||
|
||||
+13
-28
@@ -8,12 +8,11 @@ import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.extern
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.groupIdParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestPeriodTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRateParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRatePeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.nominalAnnualInterestRateParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.productIdParamName;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
@@ -94,20 +93,13 @@ public class SavingsAccountDataValidator {
|
||||
baseDataValidator.reset().parameter(externalIdParamName).value(externalId).notExceedingLengthOf(100);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(interestRateParamName, element)) {
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(interestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
if (fromApiJsonHelper.parameterExists(nominalAnnualInterestRateParamName, element)) {
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(interestRatePeriodFrequencyTypeParamName, element)) {
|
||||
final Integer interestRatePeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestRatePeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRatePeriodFrequencyTypeParamName).value(interestRatePeriodFrequencyType).notNull()
|
||||
.inMinMaxRange(1, 3);
|
||||
}
|
||||
|
||||
final Integer interestPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestPeriodTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestPeriodTypeParamName).value(interestPeriodType).notNull().inMinMaxRange(1, 7);
|
||||
final Integer interestPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCompoundingPeriodTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestPeriodType).notNull().inMinMaxRange(1, 7);
|
||||
|
||||
final Integer interestCalculationType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull().inMinMaxRange(1, 2);
|
||||
@@ -215,21 +207,14 @@ public class SavingsAccountDataValidator {
|
||||
baseDataValidator.reset().parameter(externalIdParamName).value(externalId).notExceedingLengthOf(100);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(interestRateParamName, element)) {
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(interestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
if (fromApiJsonHelper.parameterExists(nominalAnnualInterestRateParamName, element)) {
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(interestRatePeriodFrequencyTypeParamName, element)) {
|
||||
final Integer interestRatePeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestRatePeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRatePeriodFrequencyTypeParamName).value(interestRatePeriodFrequencyType).notNull()
|
||||
.inMinMaxRange(1, 3);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(interestPeriodTypeParamName, element)) {
|
||||
final Integer interestPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestPeriodTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestPeriodTypeParamName).value(interestPeriodType).notNull().inMinMaxRange(1, 7);
|
||||
if (this.fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
|
||||
final Integer interestPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCompoundingPeriodTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestPeriodType).notNull().inMinMaxRange(1, 7);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) {
|
||||
|
||||
+27
-39
@@ -20,9 +20,8 @@ public class SavingsProductData {
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final CurrencyData currency;
|
||||
private final BigDecimal interestRate;
|
||||
private final EnumOptionData interestRatePeriodFrequencyType;
|
||||
private final EnumOptionData interestPeriodType;
|
||||
private final BigDecimal nominalAnnualInterestRate;
|
||||
private final EnumOptionData interestCompoundingPeriodType;
|
||||
private final EnumOptionData interestCalculationType;
|
||||
private final EnumOptionData interestCalculationDaysInYearType;
|
||||
private final BigDecimal minRequiredOpeningBalance;
|
||||
@@ -33,9 +32,7 @@ public class SavingsProductData {
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<CurrencyData> currencyOptions;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<EnumOptionData> interestPeriodTypeOptions;
|
||||
private final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<EnumOptionData> interestCalculationTypeOptions;
|
||||
@SuppressWarnings("unused")
|
||||
@@ -43,26 +40,25 @@ public class SavingsProductData {
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
|
||||
|
||||
public static SavingsProductData template(final CurrencyData currency, final EnumOptionData interestRatePeriodFrequencyType,
|
||||
final EnumOptionData interestPeriodType, final EnumOptionData interestCalculationType,
|
||||
final EnumOptionData interestCalculationDaysInYearType, final Collection<CurrencyData> currencyOptions,
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions,
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions, final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
public static SavingsProductData template(final CurrencyData currency, final EnumOptionData interestCompoundingPeriodType,
|
||||
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
|
||||
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestPeriodTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
|
||||
|
||||
final Long id = null;
|
||||
final String name = null;
|
||||
final String description = null;
|
||||
final BigDecimal interestRate = null;
|
||||
final BigDecimal nominalAnnualInterestRate = null;
|
||||
final BigDecimal minRequiredOpeningBalance = null;
|
||||
final Integer lockinPeriodFrequency = null;
|
||||
final EnumOptionData lockinPeriodFrequencyType = null;
|
||||
|
||||
return new SavingsProductData(id, name, description, currency, interestRate, interestRatePeriodFrequencyType, interestPeriodType,
|
||||
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, currencyOptions, interestRatePeriodFrequencyTypeOptions, interestPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
lockinPeriodFrequencyType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,45 +66,41 @@ public class SavingsProductData {
|
||||
* {@link SavingsProductData} data with further template data for dropdowns.
|
||||
*/
|
||||
public static SavingsProductData withTemplate(final SavingsProductData existingProduct, final Collection<CurrencyData> currencyOptions,
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions,
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions, final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
|
||||
|
||||
return new SavingsProductData(existingProduct.id, existingProduct.name, existingProduct.description, existingProduct.currency,
|
||||
existingProduct.interestRate, existingProduct.interestRatePeriodFrequencyType, existingProduct.interestPeriodType,
|
||||
existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
|
||||
existingProduct.interestCalculationType, existingProduct.interestCalculationDaysInYearType,
|
||||
existingProduct.minRequiredOpeningBalance, existingProduct.lockinPeriodFrequency,
|
||||
existingProduct.lockinPeriodFrequencyType, currencyOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
interestPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
existingProduct.lockinPeriodFrequencyType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
public static SavingsProductData instance(final Long id, final String name, final String description, final CurrencyData currency,
|
||||
final BigDecimal interestRate, final EnumOptionData interestRatePeriodFrequencyType, final EnumOptionData interestPeriodType,
|
||||
final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
|
||||
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType) {
|
||||
|
||||
final Collection<CurrencyData> currencyOptions = null;
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
|
||||
return new SavingsProductData(id, name, description, currency, interestRate, interestRatePeriodFrequencyType, interestPeriodType,
|
||||
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, currencyOptions, interestRatePeriodFrequencyTypeOptions, interestPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
lockinPeriodFrequencyType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
public static SavingsProductData lookup(final Long id, final String name) {
|
||||
|
||||
final CurrencyData currency = null;
|
||||
final String description = null;
|
||||
final BigDecimal interestRate = null;
|
||||
final EnumOptionData interestRatePeriodFrequencyType = null;
|
||||
final EnumOptionData interestPeriodType = null;
|
||||
final BigDecimal nominalAnnualInterestRate = null;
|
||||
final EnumOptionData interestCompoundingPeriodType = null;
|
||||
final EnumOptionData interestCalculationType = null;
|
||||
final EnumOptionData interestCalculationDaysInYearType = null;
|
||||
final BigDecimal minRequiredOpeningBalance = null;
|
||||
@@ -116,24 +108,22 @@ public class SavingsProductData {
|
||||
final EnumOptionData lockinPeriodFrequencyType = null;
|
||||
|
||||
final Collection<CurrencyData> currencyOptions = null;
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
|
||||
return new SavingsProductData(id, name, description, currency, interestRate, interestRatePeriodFrequencyType, interestPeriodType,
|
||||
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, currencyOptions, interestRatePeriodFrequencyTypeOptions, interestPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
lockinPeriodFrequencyType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
private SavingsProductData(final Long id, final String name, final String description, final CurrencyData currency,
|
||||
final BigDecimal interestRate, final EnumOptionData interestRatePeriodFrequencyType, final EnumOptionData interestPeriodType,
|
||||
final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
|
||||
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
|
||||
final EnumOptionData lockinPeriodFrequencyType, final Collection<CurrencyData> currencyOptions,
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions,
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions, final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
|
||||
@@ -141,9 +131,8 @@ public class SavingsProductData {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.currency = currency;
|
||||
this.interestRate = interestRate;
|
||||
this.interestRatePeriodFrequencyType = interestRatePeriodFrequencyType;
|
||||
this.interestPeriodType = interestPeriodType;
|
||||
this.nominalAnnualInterestRate = nominalAnnualInterestRate;
|
||||
this.interestCompoundingPeriodType = interestCompoundingPeriodType;
|
||||
this.interestCalculationType = interestCalculationType;
|
||||
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType;
|
||||
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
|
||||
@@ -151,8 +140,7 @@ public class SavingsProductData {
|
||||
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType;
|
||||
|
||||
this.currencyOptions = currencyOptions;
|
||||
this.interestRatePeriodFrequencyTypeOptions = interestRatePeriodFrequencyTypeOptions;
|
||||
this.interestPeriodTypeOptions = interestPeriodTypeOptions;
|
||||
this.interestCompoundingPeriodTypeOptions = interestPeriodTypeOptions;
|
||||
this.interestCalculationTypeOptions = interestCalculationTypeOptions;
|
||||
this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions;
|
||||
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
|
||||
|
||||
+21
-27
@@ -7,13 +7,12 @@ import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.descri
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.digitsAfterDecimalParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestPeriodTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRateParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRatePeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.nameParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.nominalAnnualInterestRateParamName;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
@@ -67,16 +66,13 @@ public class SavingsProductDataValidator {
|
||||
final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerSansLocaleNamed(digitsAfterDecimalParamName, element);
|
||||
baseDataValidator.reset().parameter(digitsAfterDecimalParamName).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
|
||||
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(interestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer interestRatePeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestRatePeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRatePeriodFrequencyTypeParamName).value(interestRatePeriodFrequencyType).notNull()
|
||||
.inMinMaxRange(1, 3);
|
||||
|
||||
final Integer interestPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestPeriodTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestPeriodTypeParamName).value(interestPeriodType).notNull().inMinMaxRange(1, 7);
|
||||
final Integer interestCompoundingPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestCompoundingPeriodTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
|
||||
.inMinMaxRange(1, 8);
|
||||
|
||||
final Integer interestCalculationType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull().inMinMaxRange(1, 2);
|
||||
@@ -153,21 +149,16 @@ public class SavingsProductDataValidator {
|
||||
baseDataValidator.reset().parameter(digitsAfterDecimalParamName).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(interestRateParamName, element)) {
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(interestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
if (this.fromApiJsonHelper.parameterExists(nominalAnnualInterestRateParamName, element)) {
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(interestRatePeriodFrequencyTypeParamName, element)) {
|
||||
final Integer interestRatePeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestRatePeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRatePeriodFrequencyTypeParamName).value(interestRatePeriodFrequencyType).notNull()
|
||||
.inMinMaxRange(1, 3);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(interestPeriodTypeParamName, element)) {
|
||||
final Integer interestPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestPeriodTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestPeriodTypeParamName).value(interestPeriodType).notNull().inMinMaxRange(1, 7);
|
||||
if (this.fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
|
||||
final Integer interestCompoundingPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestCompoundingPeriodTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
|
||||
.inMinMaxRange(1, 8);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) {
|
||||
@@ -201,7 +192,10 @@ public class SavingsProductDataValidator {
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
//
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||
dataValidationErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package org.mifosplatform.portfolio.savings.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
|
||||
public class InterestCompoundingPeriodSummary {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final LocalDateInterval periodInterval;
|
||||
@SuppressWarnings("unused")
|
||||
private final BigDecimal openingBalance;
|
||||
private final BigDecimal closingBalance;
|
||||
private final BigDecimal interestEarnedUnrounded;
|
||||
private final BigDecimal cumulativeCompoundedInterestToDate;
|
||||
|
||||
public static InterestCompoundingPeriodSummary create(final LocalDateInterval periodInterval, final BigDecimal openingBalance,
|
||||
final BigDecimal closingBalance, final BigDecimal interestEarnedUnrounded, final BigDecimal cumulativeCompoundedInterestToDate) {
|
||||
return new InterestCompoundingPeriodSummary(periodInterval, openingBalance, closingBalance, interestEarnedUnrounded,
|
||||
cumulativeCompoundedInterestToDate);
|
||||
}
|
||||
|
||||
public InterestCompoundingPeriodSummary(final LocalDateInterval periodInterval, final BigDecimal openingBalance,
|
||||
final BigDecimal closingBalance, final BigDecimal interestEarnedUnrounded, final BigDecimal cumulativeCompoundedInterestToDate) {
|
||||
this.periodInterval = periodInterval;
|
||||
this.openingBalance = openingBalance;
|
||||
this.closingBalance = closingBalance;
|
||||
this.interestEarnedUnrounded = interestEarnedUnrounded;
|
||||
this.cumulativeCompoundedInterestToDate = cumulativeCompoundedInterestToDate;
|
||||
}
|
||||
|
||||
public Money closingBalance(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.closingBalance);
|
||||
}
|
||||
|
||||
public BigDecimal closingBalance() {
|
||||
return this.closingBalance;
|
||||
}
|
||||
|
||||
public BigDecimal closingBalanceWithUnroundedInterest(final MathContext mc) {
|
||||
return this.closingBalance.add(interestEarnedUnrounded, mc);
|
||||
}
|
||||
|
||||
public BigDecimal compoundedInterest() {
|
||||
return cumulativeCompoundedInterestToDate;
|
||||
}
|
||||
|
||||
public BigDecimal interestUnrounded() {
|
||||
return this.interestEarnedUnrounded;
|
||||
}
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savings.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
|
||||
public class InterestPeriodSummary {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Date startDate;
|
||||
@SuppressWarnings("unused")
|
||||
private final Date endDate;
|
||||
@SuppressWarnings("unused")
|
||||
private final Integer numberOfDays;
|
||||
@SuppressWarnings("unused")
|
||||
private final BigDecimal startingBalance;
|
||||
private final BigDecimal closingBalance;
|
||||
private final BigDecimal interestEarnedUnrounded;
|
||||
private final BigDecimal interestEarned;
|
||||
@SuppressWarnings("unused")
|
||||
private final List<SavingsAccountDailyBalance> dailyBalances;
|
||||
|
||||
public static InterestPeriodSummary from(final InterestPeriodInterval interestPeriodInterval, final Money startingBalance,
|
||||
final List<SavingsAccountDailyBalance> dailyBalances, final BigDecimal totalInterestEarnedUnrounded) {
|
||||
|
||||
return new InterestPeriodSummary(interestPeriodInterval, startingBalance, dailyBalances, totalInterestEarnedUnrounded);
|
||||
}
|
||||
|
||||
private InterestPeriodSummary(final InterestPeriodInterval interestPeriodInterval, final Money startingBalance,
|
||||
final List<SavingsAccountDailyBalance> dailyBalances, final BigDecimal totalInterestEarnedUnrounded) {
|
||||
this.startDate = interestPeriodInterval.startDate().toDate();
|
||||
this.endDate = interestPeriodInterval.endDate().toDate();
|
||||
this.numberOfDays = interestPeriodInterval.daysInPeriodInclusiveOfEndDate();
|
||||
this.startingBalance = startingBalance.getAmount();
|
||||
|
||||
final MonetaryCurrency currency = startingBalance.getCurrency();
|
||||
|
||||
this.interestEarnedUnrounded = totalInterestEarnedUnrounded;
|
||||
this.interestEarned = Money.of(currency, this.interestEarnedUnrounded).getAmount();
|
||||
|
||||
Money closingBalanceForPeriod = startingBalance.copy();
|
||||
|
||||
for (SavingsAccountDailyBalance balance : dailyBalances) {
|
||||
closingBalanceForPeriod = balance.dailyRunningBalance(currency);
|
||||
}
|
||||
|
||||
this.closingBalance = closingBalanceForPeriod.getAmount();
|
||||
this.dailyBalances = dailyBalances;
|
||||
}
|
||||
|
||||
public Money closingBalance(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.closingBalance);
|
||||
}
|
||||
|
||||
public BigDecimal interest() {
|
||||
return this.interestEarned;
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -3,16 +3,16 @@ package org.mifosplatform.portfolio.savings.domain;
|
||||
import org.joda.time.Days;
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
public class InterestPeriodInterval {
|
||||
public class LocalDateInterval {
|
||||
|
||||
private final LocalDate startDate;
|
||||
private final LocalDate endDate;
|
||||
|
||||
public static InterestPeriodInterval create(final LocalDate startDate, final LocalDate endDate) {
|
||||
return new InterestPeriodInterval(startDate, endDate);
|
||||
public static LocalDateInterval create(final LocalDate startDate, final LocalDate endDate) {
|
||||
return new LocalDateInterval(startDate, endDate);
|
||||
}
|
||||
|
||||
public InterestPeriodInterval(final LocalDate startDate, final LocalDate endDate) {
|
||||
public LocalDateInterval(final LocalDate startDate, final LocalDate endDate) {
|
||||
this.startDate = startDate;
|
||||
this.endDate = endDate;
|
||||
}
|
||||
+118
-117
@@ -81,20 +81,18 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
@Embedded
|
||||
private MonetaryCurrency currency;
|
||||
|
||||
@Column(name = "nominal_interest_rate_per_period", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal interestRate;
|
||||
|
||||
@Column(name = "nominal_interest_rate_period_frequency_enum", nullable = false)
|
||||
private Integer interestRatePeriodFrequencyType;
|
||||
@Column(name = "nominal_annual_interest_rate", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal nominalAnnualInterestRate;
|
||||
|
||||
/**
|
||||
* The interest period is the span of time at the end of which savings in a
|
||||
* client’s account earn interest.
|
||||
*
|
||||
* A value from the {@link SavingsInterestPeriodType} enumeration.
|
||||
* A value from the {@link SavingsCompoundingInterestPeriodType}
|
||||
* enumeration.
|
||||
*/
|
||||
@Column(name = "interest_period_enum", nullable = false)
|
||||
private Integer interestPeriodType;
|
||||
@Column(name = "interest_compounding_period_enum", nullable = false)
|
||||
private Integer interestCompoundingPeriodType;
|
||||
|
||||
/**
|
||||
* A value from the {@link SavingsInterestCalculationType} enumeration.
|
||||
@@ -109,9 +107,6 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
@Column(name = "interest_calculation_days_in_year_type_enum", nullable = false)
|
||||
private Integer interestCalculationDaysInYearType;
|
||||
|
||||
@Column(name = "annual_nominal_interest_rate", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal annualInterestRate;
|
||||
|
||||
@Column(name = "min_required_opening_balance", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal minRequiredOpeningBalance;
|
||||
|
||||
@@ -149,24 +144,22 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
|
||||
public static SavingsAccount createNewAccount(final Client client, final Group group, final SavingsProduct product,
|
||||
final String accountNo, final String externalId, final BigDecimal interestRate,
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType, final BigDecimal annualInterestRate,
|
||||
final SavingsInterestPeriodType interestPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||
final SavingsCompoundingInterestPeriodType interestPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency, final PeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
|
||||
final SavingsAccountStatusType status = SavingsAccountStatusType.UNACTIVATED;
|
||||
final LocalDate activationDate = null;
|
||||
return new SavingsAccount(client, group, product, accountNo, externalId, status, activationDate, interestRate,
|
||||
interestRatePeriodFrequencyType, annualInterestRate, interestPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
return new SavingsAccount(client, group, product, accountNo, externalId, status, activationDate, interestRate, interestPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType);
|
||||
}
|
||||
|
||||
private SavingsAccount(final Client client, final Group group, final SavingsProduct product, final String accountNo,
|
||||
final String externalId, final SavingsAccountStatusType status, final LocalDate activationDate, final BigDecimal interestRate,
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType, final BigDecimal annualInterestRate,
|
||||
final SavingsInterestPeriodType interestPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||
final SavingsCompoundingInterestPeriodType interestPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency, final PeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
this.client = client;
|
||||
this.group = group;
|
||||
this.product = product;
|
||||
@@ -182,10 +175,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
if (activationDate != null) {
|
||||
this.activationDate = activationDate.toDate();
|
||||
}
|
||||
this.interestRate = interestRate;
|
||||
this.interestRatePeriodFrequencyType = interestRatePeriodFrequencyType.getValue();
|
||||
this.annualInterestRate = annualInterestRate;
|
||||
this.interestPeriodType = interestPeriodType.getValue();
|
||||
this.nominalAnnualInterestRate = interestRate;
|
||||
this.interestCompoundingPeriodType = interestPeriodType.getValue();
|
||||
this.interestCalculationType = interestCalculationType.getValue();
|
||||
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType.getValue();
|
||||
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
|
||||
@@ -281,47 +272,112 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
* Interest calculation is performed on-the-fly over all account
|
||||
* transactions.
|
||||
*/
|
||||
/*
|
||||
* The daily balance method is the application of a daily interest rate to
|
||||
* the full amount of principal in the account each day. For the days the
|
||||
* account is overdrawn, a zero balance is used to calculate the interest
|
||||
* for those days.
|
||||
*/
|
||||
public void calculateInterest() {
|
||||
public void calculateInterest(final LocalDate interestCalculationEndDate) {
|
||||
|
||||
// no openingBalance concept supported yet but probably will to all for
|
||||
// migrations.
|
||||
// no openingBalance concept supported yet but probably will to allow
|
||||
// for migrations.
|
||||
final Money openingAccountBalance = Money.zero(this.currency);
|
||||
|
||||
// 1. update existing transactions so derived balance fields are
|
||||
// update existing transactions so derived balance fields are
|
||||
// correct.
|
||||
recalculateDailyBalances(openingAccountBalance);
|
||||
|
||||
// 2. determine interest periods
|
||||
final SavingsInterestPeriodType interestPeriodType = SavingsInterestPeriodType.fromInt(this.interestPeriodType);
|
||||
final SavingsInterestCalculationDaysInYearType daysInYearType = SavingsInterestCalculationDaysInYearType
|
||||
.fromInt(this.interestCalculationDaysInYearType);
|
||||
final List<InterestPeriodInterval> interestPeriods = determineInterestPeriods(getActivationLocalDate(), interestPeriodType);
|
||||
final SavingsCompoundingInterestPeriodType compoundingPeriodType = SavingsCompoundingInterestPeriodType
|
||||
.fromInt(this.interestCompoundingPeriodType);
|
||||
final List<LocalDateInterval> interestCompoundingPeriods = determineInterestCompoundingPeriods(getActivationLocalDate(),
|
||||
interestCalculationEndDate, compoundingPeriodType);
|
||||
|
||||
final List<InterestPeriodSummary> interestPeriodSummaries = deriveInterestPeriodSummaries(openingAccountBalance, interestPeriods,
|
||||
this.annualInterestRate, daysInYearType);
|
||||
// determine opening balance, daily interest rate to apply, interest
|
||||
// due, interest to compound for each period
|
||||
final List<InterestCompoundingPeriodSummary> compoundingPeriods = determineInterestCompoundingPeriodSummaries(
|
||||
openingAccountBalance, this.nominalAnnualInterestRate, daysInYearType, interestCompoundingPeriods);
|
||||
|
||||
this.summary.updateFromInterestPeriodSummaries(currency, interestPeriodSummaries);
|
||||
this.summary.updateFromInterestPeriodSummaries(currency, compoundingPeriods);
|
||||
}
|
||||
|
||||
private List<InterestPeriodInterval> determineInterestPeriods(final LocalDate activationLocalDate,
|
||||
final SavingsInterestPeriodType interestPeriodType) {
|
||||
private List<InterestCompoundingPeriodSummary> determineInterestCompoundingPeriodSummaries(final Money openingAccountBalance,
|
||||
final BigDecimal annualInterestRate, final SavingsInterestCalculationDaysInYearType daysInYearType,
|
||||
final List<LocalDateInterval> interestCompoundingPeriods) {
|
||||
|
||||
LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
List<InterestCompoundingPeriodSummary> summaries = new ArrayList<InterestCompoundingPeriodSummary>();
|
||||
|
||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
||||
final BigDecimal percentageDivisor = BigDecimal.valueOf(100l);
|
||||
final BigDecimal periodsInOneYear = determinePeriodsInOneYear(daysInYearType);
|
||||
final BigDecimal periodsInOneYearAsFraction = BigDecimal.ONE.divide(periodsInOneYear, mc);
|
||||
final BigDecimal annualInterestRateAsFraction = annualInterestRate.divide(percentageDivisor, mc);
|
||||
|
||||
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
|
||||
|
||||
final SavingsInterestCalculatorFactory interestCalculatorFactory = new SavingsInterestCalculatorFactory();
|
||||
final SavingsCompoundInterestCalculator interestCalculator = interestCalculatorFactory.createFrom(interestCalculationType,
|
||||
periodsInOneYearAsFraction, annualInterestRateAsFraction);
|
||||
|
||||
BigDecimal periodOpeningBalance = openingAccountBalance.copy().getAmount();
|
||||
BigDecimal compoundedInterestToDate = BigDecimal.ZERO;
|
||||
for (LocalDateInterval periodInterval : interestCompoundingPeriods) {
|
||||
|
||||
InterestCompoundingPeriodSummary compoundingSummary = calculateInterestCompoundingPeriodSummary(periodInterval,
|
||||
periodOpeningBalance, compoundedInterestToDate, interestCalculator);
|
||||
|
||||
periodOpeningBalance = compoundingSummary.closingBalance();
|
||||
compoundedInterestToDate = compoundingSummary.compoundedInterest();
|
||||
|
||||
summaries.add(compoundingSummary);
|
||||
}
|
||||
|
||||
return summaries;
|
||||
}
|
||||
|
||||
private InterestCompoundingPeriodSummary calculateInterestCompoundingPeriodSummary(final LocalDateInterval periodInterval,
|
||||
final BigDecimal periodOpeningBalance, final BigDecimal compoundedInterestToDate,
|
||||
final SavingsCompoundInterestCalculator interestCalculator) {
|
||||
|
||||
BigDecimal periodClosingBalance = periodOpeningBalance;
|
||||
List<SavingsAccountDailyBalance> dailyBalances = new ArrayList<SavingsAccountDailyBalance>();
|
||||
for (SavingsAccountTransaction transaction : this.transactions) {
|
||||
|
||||
if (transaction.isAcceptableForDailyBalance(periodInterval)) {
|
||||
SavingsAccountDailyBalance dailyBalance = transaction.toCompoundedDailyBalance(periodInterval.endDate(),
|
||||
compoundedInterestToDate);
|
||||
dailyBalances.add(dailyBalance);
|
||||
|
||||
periodClosingBalance = dailyBalance.endOfDayBalance();
|
||||
}
|
||||
}
|
||||
|
||||
if (dailyBalances.isEmpty()) {
|
||||
SavingsAccountDailyBalance dailyBalance = SavingsAccountDailyBalance.createFrom(periodInterval, periodOpeningBalance,
|
||||
compoundedInterestToDate);
|
||||
dailyBalances.add(dailyBalance);
|
||||
}
|
||||
|
||||
final BigDecimal totalInterestEarnedUnrounded = interestCalculator.calculate(dailyBalances,
|
||||
periodInterval.daysInPeriodInclusiveOfEndDate());
|
||||
|
||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
||||
final BigDecimal cumulativeCompoundedInterestToDate = compoundedInterestToDate.add(totalInterestEarnedUnrounded, mc);
|
||||
|
||||
return InterestCompoundingPeriodSummary.create(periodInterval, periodOpeningBalance, periodClosingBalance,
|
||||
totalInterestEarnedUnrounded, cumulativeCompoundedInterestToDate);
|
||||
}
|
||||
|
||||
private List<LocalDateInterval> determineInterestCompoundingPeriods(final LocalDate activationLocalDate,
|
||||
final LocalDate interestCalculationEndDate, final SavingsCompoundingInterestPeriodType interestPeriodType) {
|
||||
LocalDate periodStartDate = activationLocalDate;
|
||||
LocalDate periodEndDate = periodStartDate;
|
||||
|
||||
final List<InterestPeriodInterval> interestPeriods = new ArrayList<InterestPeriodInterval>();
|
||||
final List<LocalDateInterval> interestPeriods = new ArrayList<LocalDateInterval>();
|
||||
|
||||
while (!periodStartDate.isAfter(today) && !periodEndDate.isAfter(today)) {
|
||||
while (!periodStartDate.isAfter(interestCalculationEndDate) && !periodEndDate.isAfter(interestCalculationEndDate)) {
|
||||
|
||||
periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType);
|
||||
interestPeriods.add(InterestPeriodInterval.create(periodStartDate, periodEndDate));
|
||||
if (periodEndDate.isAfter(interestCalculationEndDate)) {
|
||||
periodEndDate = interestCalculationEndDate;
|
||||
}
|
||||
interestPeriods.add(LocalDateInterval.create(periodStartDate, periodEndDate));
|
||||
|
||||
// move periodStartDate forward to day after this period
|
||||
periodStartDate = periodEndDate.plusDays(1);
|
||||
@@ -330,7 +386,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
return interestPeriods;
|
||||
}
|
||||
|
||||
private LocalDate determineInterestPeriodEndDateFrom(final LocalDate periodStartDate, final SavingsInterestPeriodType interestPeriodType) {
|
||||
private LocalDate determineInterestPeriodEndDateFrom(final LocalDate periodStartDate,
|
||||
final SavingsCompoundingInterestPeriodType interestPeriodType) {
|
||||
|
||||
LocalDate periodEndDate = DateUtils.getLocalDateOfTenant();
|
||||
|
||||
@@ -366,7 +423,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
|
||||
}
|
||||
break;
|
||||
case SEMIANNUAL:
|
||||
case BI_ANNUAL:
|
||||
// jan 1st to 30, jul 1st to dec 31
|
||||
year = periodStartDate.getYearOfEra();
|
||||
monthofYear = periodStartDate.getMonthOfYear();
|
||||
@@ -380,6 +437,10 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
||||
periodEndDate = periodStartDate.dayOfMonth().withMaximumValue();
|
||||
break;
|
||||
case NO_COMPOUNDING_SIMPLE_INTEREST:
|
||||
periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
||||
periodEndDate = periodStartDate.dayOfMonth().withMaximumValue();
|
||||
break;
|
||||
}
|
||||
|
||||
return periodEndDate;
|
||||
@@ -403,62 +464,6 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
return periodsInOneYear;
|
||||
}
|
||||
|
||||
private List<InterestPeriodSummary> deriveInterestPeriodSummaries(final Money openingAccountBalance,
|
||||
final List<InterestPeriodInterval> interestPeriods, final BigDecimal annualInterestRate,
|
||||
final SavingsInterestCalculationDaysInYearType daysInYearType) {
|
||||
|
||||
final List<InterestPeriodSummary> summaries = new ArrayList<InterestPeriodSummary>();
|
||||
|
||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
||||
final BigDecimal percentageDivisor = BigDecimal.valueOf(100l);
|
||||
final BigDecimal periodsInOneYear = determinePeriodsInOneYear(daysInYearType);
|
||||
final BigDecimal periodsInOneYearAsFraction = BigDecimal.ONE.divide(periodsInOneYear, mc);
|
||||
final BigDecimal annualInterestRateAsFraction = annualInterestRate.divide(percentageDivisor, mc);
|
||||
|
||||
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
|
||||
|
||||
final SavingsInterestCalculatorFactory interestCalculatorFactory = new SavingsInterestCalculatorFactory();
|
||||
final SavingsInterestCalculator interestCalculator = interestCalculatorFactory.createFrom(interestCalculationType,
|
||||
periodsInOneYearAsFraction, annualInterestRateAsFraction);
|
||||
|
||||
Money periodOpeningBalance = openingAccountBalance.copy();
|
||||
for (InterestPeriodInterval interestPeriodInterval : interestPeriods) {
|
||||
|
||||
InterestPeriodSummary interestPeriodSummary = calculateInterestPeriodSummaryFor(interestPeriodInterval, periodOpeningBalance,
|
||||
interestCalculator);
|
||||
|
||||
periodOpeningBalance = interestPeriodSummary.closingBalance(this.currency);
|
||||
|
||||
summaries.add(interestPeriodSummary);
|
||||
}
|
||||
|
||||
return summaries;
|
||||
}
|
||||
|
||||
private InterestPeriodSummary calculateInterestPeriodSummaryFor(final InterestPeriodInterval interestPeriodInterval,
|
||||
final Money startingBalanceForPeriod, final SavingsInterestCalculator interestCalculator) {
|
||||
|
||||
List<SavingsAccountDailyBalance> dailyBalances = new ArrayList<SavingsAccountDailyBalance>();
|
||||
for (SavingsAccountTransaction transaction : this.transactions) {
|
||||
|
||||
if (transaction.isAcceptableForDailyBalance(interestPeriodInterval)) {
|
||||
SavingsAccountDailyBalance dailyBalance = transaction.toDailyBalance(interestPeriodInterval.endDate());
|
||||
dailyBalances.add(dailyBalance);
|
||||
}
|
||||
}
|
||||
|
||||
if (dailyBalances.isEmpty()) {
|
||||
SavingsAccountDailyBalance dailyBalance = SavingsAccountDailyBalance.createFrom(interestPeriodInterval,
|
||||
startingBalanceForPeriod.getAmount());
|
||||
dailyBalances.add(dailyBalance);
|
||||
}
|
||||
|
||||
final BigDecimal totalInterestEarnedUnrounded = interestCalculator.calculate(dailyBalances,
|
||||
interestPeriodInterval.daysInPeriodInclusiveOfEndDate());
|
||||
|
||||
return InterestPeriodSummary.from(interestPeriodInterval, startingBalanceForPeriod, dailyBalances, totalInterestEarnedUnrounded);
|
||||
}
|
||||
|
||||
private void recalculateDailyBalances(final Money openingAccountBalance) {
|
||||
|
||||
Money runningBalance = openingAccountBalance.copy();
|
||||
@@ -537,7 +542,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
|
||||
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
||||
|
||||
calculateInterest();
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
calculateInterest(today);
|
||||
|
||||
return transaction;
|
||||
}
|
||||
@@ -614,7 +620,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
|
||||
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
||||
|
||||
calculateInterest();
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
calculateInterest(today);
|
||||
|
||||
return transaction;
|
||||
}
|
||||
@@ -683,18 +690,12 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
actualChanges.put(SavingsApiConstants.productIdParamName, newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(SavingsApiConstants.interestRateParamName, this.interestRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(SavingsApiConstants.interestRateParamName);
|
||||
actualChanges.put(SavingsApiConstants.interestRateParamName, newValue);
|
||||
if (command.isChangeInBigDecimalParameterNamed(SavingsApiConstants.nominalAnnualInterestRateParamName,
|
||||
this.nominalAnnualInterestRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(SavingsApiConstants.nominalAnnualInterestRateParamName);
|
||||
actualChanges.put(SavingsApiConstants.nominalAnnualInterestRateParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.interestRate = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(SavingsApiConstants.interestRatePeriodFrequencyTypeParamName,
|
||||
this.interestRatePeriodFrequencyType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(SavingsApiConstants.interestRatePeriodFrequencyTypeParamName);
|
||||
actualChanges.put(SavingsApiConstants.interestRatePeriodFrequencyTypeParamName, newValue);
|
||||
this.interestRatePeriodFrequencyType = PeriodFrequencyType.fromInt(newValue).getValue();
|
||||
this.nominalAnnualInterestRate = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(SavingsApiConstants.minRequiredOpeningBalanceParamName,
|
||||
|
||||
+12
-31
@@ -9,12 +9,11 @@ import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.activa
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.activeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestPeriodTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRateParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRatePeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.nominalAnnualInterestRateParamName;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Locale;
|
||||
@@ -30,8 +29,6 @@ import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
||||
import org.mifosplatform.portfolio.group.domain.Group;
|
||||
import org.mifosplatform.portfolio.group.domain.GroupRepository;
|
||||
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savings.exception.SavingsProductNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -46,18 +43,15 @@ public class SavingsAccountAssembler {
|
||||
private final GroupRepository groupRepository;
|
||||
private final SavingsProductRepository savingProductRepository;
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
private final AprCalculator aprCalculator;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountAssembler(final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper,
|
||||
final ClientRepository clientRepository, final GroupRepository groupRepository,
|
||||
final SavingsProductRepository savingProductRepository, final AprCalculator aprCalculator,
|
||||
final FromJsonHelper fromApiJsonHelper) {
|
||||
final SavingsProductRepository savingProductRepository, final FromJsonHelper fromApiJsonHelper) {
|
||||
this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
|
||||
this.clientRepository = clientRepository;
|
||||
this.groupRepository = groupRepository;
|
||||
this.savingProductRepository = savingProductRepository;
|
||||
this.aprCalculator = aprCalculator;
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
@@ -93,8 +87,8 @@ public class SavingsAccountAssembler {
|
||||
}
|
||||
|
||||
BigDecimal interestRate = null;
|
||||
if (command.parameterExists(interestRateParamName)) {
|
||||
interestRate = command.bigDecimalValueOfParameterNamed(interestRateParamName);
|
||||
if (command.parameterExists(nominalAnnualInterestRateParamName)) {
|
||||
interestRate = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName);
|
||||
} else {
|
||||
interestRate = product.interestRate();
|
||||
}
|
||||
@@ -102,23 +96,10 @@ public class SavingsAccountAssembler {
|
||||
final boolean active = fromApiJsonHelper.extractBooleanNamed(activeParamName, element);
|
||||
final LocalDate activationDate = fromApiJsonHelper.extractLocalDateNamed(activationDateParamName, element);
|
||||
|
||||
PeriodFrequencyType interestRatePeriodFrequencyType = null;
|
||||
Integer interestRatePeriodFrequencyTypeValue = null;
|
||||
if (command.parameterExists(interestRatePeriodFrequencyTypeParamName)) {
|
||||
interestRatePeriodFrequencyTypeValue = command.integerValueOfParameterNamed(interestRatePeriodFrequencyTypeParamName);
|
||||
if (interestRatePeriodFrequencyTypeValue != null) {
|
||||
interestRatePeriodFrequencyType = PeriodFrequencyType.fromInt(interestRatePeriodFrequencyTypeValue);
|
||||
}
|
||||
} else {
|
||||
interestRatePeriodFrequencyType = product.interestRatePeriodFrequencyType();
|
||||
}
|
||||
|
||||
final BigDecimal annualInterestRate = this.aprCalculator.calculateFrom(interestRatePeriodFrequencyType, interestRate);
|
||||
|
||||
SavingsInterestPeriodType interestPeriodType = null;
|
||||
final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestPeriodTypeParamName);
|
||||
SavingsCompoundingInterestPeriodType interestPeriodType = null;
|
||||
final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName);
|
||||
if (interestPeriodTypeValue != null) {
|
||||
interestPeriodType = SavingsInterestPeriodType.fromInt(interestPeriodTypeValue);
|
||||
interestPeriodType = SavingsCompoundingInterestPeriodType.fromInt(interestPeriodTypeValue);
|
||||
}
|
||||
|
||||
SavingsInterestCalculationType interestCalculationType = null;
|
||||
@@ -148,20 +129,20 @@ public class SavingsAccountAssembler {
|
||||
lockinPeriodFrequency = product.lockinPeriodFrequency();
|
||||
}
|
||||
|
||||
PeriodFrequencyType lockinPeriodFrequencyType = null;
|
||||
SavingsPeriodFrequencyType lockinPeriodFrequencyType = null;
|
||||
Integer lockinPeriodFrequencyTypeValue = null;
|
||||
if (command.parameterExists(lockinPeriodFrequencyTypeParamName)) {
|
||||
lockinPeriodFrequencyTypeValue = command.integerValueOfParameterNamed(lockinPeriodFrequencyTypeParamName);
|
||||
if (lockinPeriodFrequencyTypeValue != null) {
|
||||
lockinPeriodFrequencyType = PeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
|
||||
lockinPeriodFrequencyType = SavingsPeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
|
||||
}
|
||||
} else {
|
||||
lockinPeriodFrequencyType = product.lockinPeriodFrequencyType();
|
||||
}
|
||||
|
||||
final SavingsAccount account = SavingsAccount.createNewAccount(client, group, product, accountNo, externalId, interestRate,
|
||||
interestRatePeriodFrequencyType, annualInterestRate, interestPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
interestPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
account.setHelpers(this.savingsAccountTransactionSummaryWrapper);
|
||||
|
||||
if (active) {
|
||||
|
||||
+20
-10
@@ -9,24 +9,32 @@ import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
|
||||
public class SavingsAccountDailyBalance {
|
||||
|
||||
private final InterestPeriodInterval interestPeriodInterval;
|
||||
private final BigDecimal runningBalance;
|
||||
private final LocalDateInterval interestPeriodInterval;
|
||||
private final BigDecimal endOfDayBalance;
|
||||
private final BigDecimal cumulativeBalance;
|
||||
private final BigDecimal compoundedInterestToDate;
|
||||
|
||||
public static SavingsAccountDailyBalance createFrom(final InterestPeriodInterval interestPeriodInterval, final BigDecimal runningBalance) {
|
||||
return new SavingsAccountDailyBalance(interestPeriodInterval, runningBalance);
|
||||
public static SavingsAccountDailyBalance createFrom(final LocalDateInterval interestPeriodInterval, final BigDecimal endOfDayBalance,
|
||||
final BigDecimal compoundedInterestToDate) {
|
||||
return new SavingsAccountDailyBalance(interestPeriodInterval, endOfDayBalance, compoundedInterestToDate);
|
||||
}
|
||||
|
||||
private SavingsAccountDailyBalance(final InterestPeriodInterval interestPeriodInterval, final BigDecimal runningBalance) {
|
||||
private SavingsAccountDailyBalance(final LocalDateInterval interestPeriodInterval, final BigDecimal endOfDayBalance,
|
||||
final BigDecimal compoundedInterestToDate) {
|
||||
this.interestPeriodInterval = interestPeriodInterval;
|
||||
this.runningBalance = runningBalance;
|
||||
this.endOfDayBalance = endOfDayBalance;
|
||||
this.compoundedInterestToDate = compoundedInterestToDate;
|
||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
||||
final BigDecimal numberOfDaysBigDecimal = BigDecimal.valueOf(interestPeriodInterval.daysInPeriodInclusiveOfEndDate());
|
||||
this.cumulativeBalance = runningBalance.multiply(numberOfDaysBigDecimal, mc);
|
||||
this.cumulativeBalance = endOfDayBalance.multiply(numberOfDaysBigDecimal, mc);
|
||||
}
|
||||
|
||||
public Money dailyRunningBalance(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, runningBalance);
|
||||
return Money.of(currency, endOfDayBalance);
|
||||
}
|
||||
|
||||
public BigDecimal endOfDayBalance() {
|
||||
return this.endOfDayBalance;
|
||||
}
|
||||
|
||||
public BigDecimal cumulativeBalance() {
|
||||
@@ -38,12 +46,14 @@ public class SavingsAccountDailyBalance {
|
||||
}
|
||||
|
||||
public boolean isGreaterThanZero() {
|
||||
return this.runningBalance.compareTo(BigDecimal.ZERO) > 0;
|
||||
return this.endOfDayBalance.compareTo(BigDecimal.ZERO) > 0;
|
||||
}
|
||||
|
||||
public BigDecimal interestUsingDailyBalanceMethod(final BigDecimal dailyInterestRate, final Integer numberOfDays) {
|
||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
||||
final BigDecimal numberOfDaysBigDecimal = BigDecimal.valueOf(numberOfDays.longValue());
|
||||
return this.runningBalance.multiply(dailyInterestRate, mc).multiply(numberOfDaysBigDecimal, mc);
|
||||
|
||||
final BigDecimal compoundedEndOfDayBalance = this.endOfDayBalance.add(this.compoundedInterestToDate, mc);
|
||||
return compoundedEndOfDayBalance.multiply(dailyInterestRate, mc).multiply(numberOfDaysBigDecimal, mc);
|
||||
}
|
||||
}
|
||||
+11
-5
@@ -47,13 +47,19 @@ public final class SavingsAccountSummary {
|
||||
.getAmount();
|
||||
}
|
||||
|
||||
public void updateFromInterestPeriodSummaries(final MonetaryCurrency currency, final List<InterestPeriodSummary> interestPeriodSummaries) {
|
||||
Money totalInterestEarned = Money.zero(currency);
|
||||
for (InterestPeriodSummary interestPeriodSummary : interestPeriodSummaries) {
|
||||
totalInterestEarned = totalInterestEarned.plus(interestPeriodSummary.interest());
|
||||
public void updateFromInterestPeriodSummaries(final MonetaryCurrency currency,
|
||||
final List<InterestCompoundingPeriodSummary> compoundingPeriods) {
|
||||
|
||||
// get the max compounded interest
|
||||
final BigDecimal compoundedInterestToDate = compoundingPeriods.get(compoundingPeriods.size() - 1).compoundedInterest();
|
||||
final Money maxIntrestCompoundedToDate = Money.of(currency, compoundedInterestToDate);
|
||||
|
||||
BigDecimal totalInterestUnrounded = BigDecimal.ZERO;
|
||||
for (InterestCompoundingPeriodSummary interestPeriodSummary : compoundingPeriods) {
|
||||
totalInterestUnrounded = totalInterestUnrounded.add(interestPeriodSummary.interestUnrounded());
|
||||
}
|
||||
|
||||
this.totalInterestEarned = totalInterestEarned.getAmountDefaultedToNullIfZero();
|
||||
this.totalInterestEarned = maxIntrestCompoundedToDate.getAmountDefaultedToNullIfZero();
|
||||
}
|
||||
|
||||
public boolean isLessThanOrEqualToAccountBalance(final Money amount) {
|
||||
|
||||
+14
-4
@@ -130,7 +130,7 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
||||
|
||||
public void updateCumulativeBalanceAndDates(final MonetaryCurrency currency, final LocalDate endOfBalanceDate) {
|
||||
this.balanceEndDate = endOfBalanceDate.toDate();
|
||||
this.balanceNumberOfDays = InterestPeriodInterval.create(getTransactionLocalDate(), endOfBalanceDate)
|
||||
this.balanceNumberOfDays = LocalDateInterval.create(getTransactionLocalDate(), endOfBalanceDate)
|
||||
.daysInPeriodInclusiveOfEndDate();
|
||||
this.cumulativeBalance = Money.of(currency, this.runningBalance).multipliedBy(this.balanceNumberOfDays).getAmount();
|
||||
}
|
||||
@@ -147,7 +147,7 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
||||
return endDate;
|
||||
}
|
||||
|
||||
public boolean isAcceptableForDailyBalance(final InterestPeriodInterval interestPeriodInterval) {
|
||||
public boolean isAcceptableForDailyBalance(final LocalDateInterval interestPeriodInterval) {
|
||||
return isNotReversed() && interestPeriodInterval.contains(getTransactionLocalDate()) && isABalanceForAtLeastOneDay();
|
||||
}
|
||||
|
||||
@@ -162,7 +162,17 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
||||
balanceValidTo = periodEnd;
|
||||
}
|
||||
|
||||
final InterestPeriodInterval interestPeriodInterval = InterestPeriodInterval.create(getTransactionLocalDate(), balanceValidTo);
|
||||
return SavingsAccountDailyBalance.createFrom(interestPeriodInterval, this.runningBalance);
|
||||
final LocalDateInterval interestPeriodInterval = LocalDateInterval.create(getTransactionLocalDate(), balanceValidTo);
|
||||
return SavingsAccountDailyBalance.createFrom(interestPeriodInterval, this.runningBalance, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public SavingsAccountDailyBalance toCompoundedDailyBalance(final LocalDate periodEnd, final BigDecimal compoundedInterestToDate) {
|
||||
LocalDate balanceValidTo = getEndOfBalanceLocalDate();
|
||||
if (periodEnd.isBefore(getEndOfBalanceLocalDate())) {
|
||||
balanceValidTo = periodEnd;
|
||||
}
|
||||
|
||||
final LocalDateInterval interestPeriodInterval = LocalDateInterval.create(getTransactionLocalDate(), balanceValidTo);
|
||||
return SavingsAccountDailyBalance.createFrom(interestPeriodInterval, this.runningBalance, compoundedInterestToDate);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -3,7 +3,7 @@ package org.mifosplatform.portfolio.savings.domain;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
public interface SavingsInterestCalculator {
|
||||
public interface SavingsCompoundInterestCalculator {
|
||||
|
||||
BigDecimal calculate(List<SavingsAccountDailyBalance> dailyBalances, Integer numberOfDays);
|
||||
|
||||
+2
-2
@@ -9,12 +9,12 @@ import java.util.List;
|
||||
* Calculates interest on a savings account using the <b>Average Balance</b>
|
||||
* method.
|
||||
*/
|
||||
public class SavingsInterestCalculatorForAverageBalance implements SavingsInterestCalculator {
|
||||
public class SavingsCompoundInterestCalculatorForAverageBalance implements SavingsCompoundInterestCalculator {
|
||||
|
||||
private final BigDecimal periodsInOneYearAsFraction;
|
||||
private final BigDecimal annualInterestRateAsFraction;
|
||||
|
||||
public SavingsInterestCalculatorForAverageBalance(final BigDecimal periodsInOneYearAsFraction,
|
||||
public SavingsCompoundInterestCalculatorForAverageBalance(final BigDecimal periodsInOneYearAsFraction,
|
||||
final BigDecimal annualInterestRateAsFraction) {
|
||||
this.periodsInOneYearAsFraction = periodsInOneYearAsFraction;
|
||||
this.annualInterestRateAsFraction = annualInterestRateAsFraction;
|
||||
+3
-3
@@ -9,12 +9,12 @@ import java.util.List;
|
||||
* Calculates interest on a savings account using the <b>Daily Balance</b>
|
||||
* method.
|
||||
*/
|
||||
public class SavingsInterestCalculatorForDailyBalance implements SavingsInterestCalculator {
|
||||
public class SavingsCompoundInterestCalculatorForDailyBalance implements SavingsCompoundInterestCalculator {
|
||||
|
||||
private final BigDecimal periodsInOneYearAsFraction;
|
||||
private final BigDecimal annualInterestRateAsFraction;
|
||||
|
||||
public SavingsInterestCalculatorForDailyBalance(final BigDecimal periodsInOneYearAsFraction,
|
||||
public SavingsCompoundInterestCalculatorForDailyBalance(final BigDecimal periodsInOneYearAsFraction,
|
||||
final BigDecimal annualInterestRateAsFraction) {
|
||||
this.periodsInOneYearAsFraction = periodsInOneYearAsFraction;
|
||||
this.annualInterestRateAsFraction = annualInterestRateAsFraction;
|
||||
@@ -29,7 +29,7 @@ public class SavingsInterestCalculatorForDailyBalance implements SavingsInterest
|
||||
|
||||
for (SavingsAccountDailyBalance balance : dailyBalances) {
|
||||
if (balance.isGreaterThanZero()) {
|
||||
final BigDecimal interestForBalance = balance.interestUsingDailyBalanceMethod(dailyInterestRate, numberOfDays);
|
||||
final BigDecimal interestForBalance = balance.interestUsingDailyBalanceMethod(dailyInterestRate, balance.numberOfDays());
|
||||
interestCalculated = interestCalculated.add(interestForBalance, mc);
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.savings.domain;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The compounding interest period is the span of time at the end of which
|
||||
* savings in a client’s account earn interest.
|
||||
* </p>
|
||||
*/
|
||||
public enum SavingsCompoundingInterestPeriodType {
|
||||
|
||||
INVALID(0, "savingsCompoundingInterestPeriodType.invalid"), //
|
||||
DAILY(1, "savingsCompoundingInterestPeriodType.daily"), //
|
||||
WEEKLY(2, "savingsCompoundingInterestPeriodType.weekly"), //
|
||||
BIWEEKLY(3, "savingsCompoundingInterestPeriodType.biweekly"), //
|
||||
MONTHLY(4, "savingsCompoundingInterestPeriodType.monthly"), //
|
||||
QUATERLY(5, "savingsCompoundingInterestPeriodType.quarterly"), //
|
||||
BI_ANNUAL(6, "savingsCompoundingInterestPeriodType.biannual"), //
|
||||
ANNUAL(7, "savingsCompoundingInterestPeriodType.annual"), //
|
||||
NO_COMPOUNDING_SIMPLE_INTEREST(8, "savingsCompoundingInterestPeriodType.nocompounding");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
private SavingsCompoundingInterestPeriodType(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static SavingsCompoundingInterestPeriodType fromInt(final Integer type) {
|
||||
SavingsCompoundingInterestPeriodType repaymentFrequencyType = SavingsCompoundingInterestPeriodType.INVALID;
|
||||
if (type != null) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
repaymentFrequencyType = SavingsCompoundingInterestPeriodType.DAILY;
|
||||
break;
|
||||
case 2:
|
||||
repaymentFrequencyType = SavingsCompoundingInterestPeriodType.WEEKLY;
|
||||
break;
|
||||
case 3:
|
||||
repaymentFrequencyType = SavingsCompoundingInterestPeriodType.BIWEEKLY;
|
||||
break;
|
||||
case 4:
|
||||
repaymentFrequencyType = SavingsCompoundingInterestPeriodType.MONTHLY;
|
||||
break;
|
||||
case 5:
|
||||
repaymentFrequencyType = SavingsCompoundingInterestPeriodType.QUATERLY;
|
||||
break;
|
||||
case 6:
|
||||
repaymentFrequencyType = SavingsCompoundingInterestPeriodType.BI_ANNUAL;
|
||||
break;
|
||||
case 7:
|
||||
repaymentFrequencyType = SavingsCompoundingInterestPeriodType.ANNUAL;
|
||||
break;
|
||||
case 8:
|
||||
repaymentFrequencyType = SavingsCompoundingInterestPeriodType.NO_COMPOUNDING_SIMPLE_INTEREST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return repaymentFrequencyType;
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -4,18 +4,18 @@ import java.math.BigDecimal;
|
||||
|
||||
public class SavingsInterestCalculatorFactory {
|
||||
|
||||
public SavingsInterestCalculator createFrom(final SavingsInterestCalculationType interestCalculationType,
|
||||
public SavingsCompoundInterestCalculator createFrom(final SavingsInterestCalculationType interestCalculationType,
|
||||
final BigDecimal periodsInOneYearAsFraction, final BigDecimal annualInterestRateAsFraction) {
|
||||
|
||||
SavingsInterestCalculator savingsInterestCalculator = new SavingsInterestCalculatorForDailyBalance(periodsInOneYearAsFraction,
|
||||
SavingsCompoundInterestCalculator savingsInterestCalculator = new SavingsCompoundInterestCalculatorForDailyBalance(periodsInOneYearAsFraction,
|
||||
annualInterestRateAsFraction);
|
||||
switch (interestCalculationType) {
|
||||
case AVERAGE_DAILY_BALANCE:
|
||||
savingsInterestCalculator = new SavingsInterestCalculatorForAverageBalance(periodsInOneYearAsFraction,
|
||||
savingsInterestCalculator = new SavingsCompoundInterestCalculatorForAverageBalance(periodsInOneYearAsFraction,
|
||||
annualInterestRateAsFraction);
|
||||
break;
|
||||
case DAILY_BALANCE:
|
||||
savingsInterestCalculator = new SavingsInterestCalculatorForDailyBalance(periodsInOneYearAsFraction,
|
||||
savingsInterestCalculator = new SavingsCompoundInterestCalculatorForDailyBalance(periodsInOneYearAsFraction,
|
||||
annualInterestRateAsFraction);
|
||||
break;
|
||||
case INVALID:
|
||||
|
||||
-75
@@ -1,75 +0,0 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.savings.domain;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The interest period is the span of time at the end of which savings in a
|
||||
* client’s account earn interest.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Interest periods may differ for different types of savings products. In all
|
||||
* cases, savings accounts must have established and published interest periods.
|
||||
* </p>
|
||||
*/
|
||||
public enum SavingsInterestPeriodType {
|
||||
|
||||
INVALID(0, "savingsCalculationPeriodType.invalid"), //
|
||||
DAILY(1, "savingsCalculationPeriodType.daily"), //
|
||||
WEEKLY(2, "savingsCalculationPeriodType.weekly"), //
|
||||
BIWEEKLY(3, "savingsCalculationPeriodType.biweekly"), //
|
||||
MONTHLY(4, "savingsCalculationPeriodType.monthly"), //
|
||||
QUATERLY(5, "savingsCalculationPeriodType.quarterly"), //
|
||||
SEMIANNUAL(6, "savingsCalculationPeriodType.semiannual"), //
|
||||
ANNUAL(7, "savingsCalculationPeriodType.annual");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
private SavingsInterestPeriodType(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static SavingsInterestPeriodType fromInt(final Integer type) {
|
||||
SavingsInterestPeriodType repaymentFrequencyType = SavingsInterestPeriodType.INVALID;
|
||||
if (type != null) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
repaymentFrequencyType = SavingsInterestPeriodType.DAILY;
|
||||
break;
|
||||
case 2:
|
||||
repaymentFrequencyType = SavingsInterestPeriodType.WEEKLY;
|
||||
break;
|
||||
case 3:
|
||||
repaymentFrequencyType = SavingsInterestPeriodType.BIWEEKLY;
|
||||
break;
|
||||
case 4:
|
||||
repaymentFrequencyType = SavingsInterestPeriodType.MONTHLY;
|
||||
break;
|
||||
case 5:
|
||||
repaymentFrequencyType = SavingsInterestPeriodType.QUATERLY;
|
||||
break;
|
||||
case 6:
|
||||
repaymentFrequencyType = SavingsInterestPeriodType.SEMIANNUAL;
|
||||
break;
|
||||
case 7:
|
||||
repaymentFrequencyType = SavingsInterestPeriodType.ANNUAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return repaymentFrequencyType;
|
||||
}
|
||||
}
|
||||
+28
-51
@@ -10,14 +10,13 @@ import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.descri
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.digitsAfterDecimalParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestPeriodTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRateParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRatePeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.localeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.nameParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.nominalAnnualInterestRateParamName;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -31,7 +30,6 @@ import javax.persistence.Table;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savings.exception.InvalidSavingsProductSettingsException;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@@ -48,20 +46,17 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
@Embedded
|
||||
private MonetaryCurrency currency;
|
||||
|
||||
@Column(name = "nominal_interest_rate_per_period", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal interestRate;
|
||||
|
||||
@Column(name = "nominal_interest_rate_period_frequency_enum", nullable = false)
|
||||
private Integer interestRatePeriodFrequencyType;
|
||||
@Column(name = "nominal_annual_interest_rate", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal nominalAnnualInterestRate;
|
||||
|
||||
/**
|
||||
* The interest period is the span of time at the end of which savings in a
|
||||
* client’s account earn interest.
|
||||
*
|
||||
* A value from the {@link SavingsInterestPeriodType} enumeration.
|
||||
* A value from the {@link SavingsCompoundingInterestPeriodType} enumeration.
|
||||
*/
|
||||
@Column(name = "interest_period_enum", nullable = false)
|
||||
private Integer interestPeriodType;
|
||||
@Column(name = "interest_compounding_period_enum", nullable = false)
|
||||
private Integer interestCompoundingPeriodType;
|
||||
|
||||
/**
|
||||
* A value from the {@link SavingsInterestCalculationType} enumeration.
|
||||
@@ -86,15 +81,13 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
private Integer lockinPeriodFrequencyType;
|
||||
|
||||
public static SavingsProduct createNew(final String name, final String description, final MonetaryCurrency currency,
|
||||
final BigDecimal interestRate, final SavingsPeriodFrequencyType interestRatePeriodFrequencyType,
|
||||
final SavingsInterestPeriodType interestPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||
final BigDecimal interestRate, final SavingsCompoundingInterestPeriodType interestPeriodType,
|
||||
final SavingsInterestCalculationType interestCalculationType,
|
||||
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency,
|
||||
final PeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
|
||||
return new SavingsProduct(name, description, currency, interestRate, interestRatePeriodFrequencyType, interestPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType);
|
||||
return new SavingsProduct(name, description, currency, interestRate, interestPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
}
|
||||
|
||||
protected SavingsProduct() {
|
||||
@@ -103,18 +96,16 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
private SavingsProduct(final String name, final String description, final MonetaryCurrency currency, final BigDecimal interestRate,
|
||||
final SavingsPeriodFrequencyType interestRatePeriodFrequencyType, final SavingsInterestPeriodType interestPeriodType,
|
||||
final SavingsInterestCalculationType interestCalculationType,
|
||||
final SavingsCompoundingInterestPeriodType interestPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency, final PeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
|
||||
this.currency = currency;
|
||||
this.interestRate = interestRate;
|
||||
this.interestRatePeriodFrequencyType = interestRatePeriodFrequencyType.getValue();
|
||||
this.interestPeriodType = interestPeriodType.getValue();
|
||||
this.nominalAnnualInterestRate = interestRate;
|
||||
this.interestCompoundingPeriodType = interestPeriodType.getValue();
|
||||
this.interestCalculationType = interestCalculationType.getValue();
|
||||
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType.getValue();
|
||||
|
||||
@@ -135,15 +126,7 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public BigDecimal interestRate() {
|
||||
return Money.of(this.currency, this.interestRate).getAmount();
|
||||
}
|
||||
|
||||
public PeriodFrequencyType interestRatePeriodFrequencyType() {
|
||||
PeriodFrequencyType type = null;
|
||||
if (this.interestRatePeriodFrequencyType != null) {
|
||||
type = PeriodFrequencyType.fromInt(this.interestRatePeriodFrequencyType);
|
||||
}
|
||||
return type;
|
||||
return Money.of(this.currency, this.nominalAnnualInterestRate).getAmount();
|
||||
}
|
||||
|
||||
public BigDecimal minRequiredOpeningBalance() {
|
||||
@@ -154,10 +137,10 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
return this.lockinPeriodFrequency;
|
||||
}
|
||||
|
||||
public PeriodFrequencyType lockinPeriodFrequencyType() {
|
||||
PeriodFrequencyType type = null;
|
||||
public SavingsPeriodFrequencyType lockinPeriodFrequencyType() {
|
||||
SavingsPeriodFrequencyType type = null;
|
||||
if (this.lockinPeriodFrequencyType != null) {
|
||||
type = PeriodFrequencyType.fromInt(this.lockinPeriodFrequencyType);
|
||||
type = SavingsPeriodFrequencyType.fromInt(this.lockinPeriodFrequencyType);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
@@ -197,23 +180,17 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
this.currency = new MonetaryCurrency(currencyCode, this.currency.getDigitsAfterDecimal());
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(interestRateParamName, this.interestRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(interestRateParamName);
|
||||
actualChanges.put(interestRateParamName, newValue);
|
||||
if (command.isChangeInBigDecimalParameterNamed(nominalAnnualInterestRateParamName, this.nominalAnnualInterestRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName);
|
||||
actualChanges.put(nominalAnnualInterestRateParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
this.interestRate = newValue;
|
||||
this.nominalAnnualInterestRate = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(interestRatePeriodFrequencyTypeParamName, this.interestRatePeriodFrequencyType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestRatePeriodFrequencyTypeParamName);
|
||||
actualChanges.put(interestRatePeriodFrequencyTypeParamName, newValue);
|
||||
this.interestRatePeriodFrequencyType = SavingsPeriodFrequencyType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(interestPeriodTypeParamName, this.interestPeriodType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestPeriodTypeParamName);
|
||||
actualChanges.put(interestPeriodTypeParamName, newValue);
|
||||
this.interestPeriodType = SavingsInterestPeriodType.fromInt(newValue).getValue();
|
||||
if (command.isChangeInIntegerParameterNamed(interestCompoundingPeriodTypeParamName, this.interestCompoundingPeriodType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName);
|
||||
actualChanges.put(interestCompoundingPeriodTypeParamName, newValue);
|
||||
this.interestCompoundingPeriodType = SavingsCompoundingInterestPeriodType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(interestCalculationTypeParamName, this.interestCalculationType)) {
|
||||
|
||||
+10
-18
@@ -5,19 +5,17 @@ import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.descri
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.digitsAfterDecimalParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestPeriodTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRateParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRatePeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.nameParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.nominalAnnualInterestRateParamName;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@@ -32,17 +30,12 @@ public class SavingsProductAssembler {
|
||||
final Integer digitsAfterDecimal = command.integerValueOfParameterNamed(digitsAfterDecimalParamName);
|
||||
MonetaryCurrency currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal);
|
||||
|
||||
final BigDecimal interestRate = command.bigDecimalValueOfParameterNamed(interestRateParamName);
|
||||
SavingsPeriodFrequencyType interestRatePeriodFrequencyType = null;
|
||||
final Integer interestRatePeriodFrequencyTypeValue = command.integerValueOfParameterNamed(interestRatePeriodFrequencyTypeParamName);
|
||||
if (interestRatePeriodFrequencyTypeValue != null) {
|
||||
interestRatePeriodFrequencyType = SavingsPeriodFrequencyType.fromInt(interestRatePeriodFrequencyTypeValue);
|
||||
}
|
||||
final BigDecimal interestRate = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName);
|
||||
|
||||
SavingsInterestPeriodType interestPeriodType = null;
|
||||
final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestPeriodTypeParamName);
|
||||
SavingsCompoundingInterestPeriodType interestPeriodType = null;
|
||||
final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName);
|
||||
if (interestPeriodTypeValue != null) {
|
||||
interestPeriodType = SavingsInterestPeriodType.fromInt(interestPeriodTypeValue);
|
||||
interestPeriodType = SavingsCompoundingInterestPeriodType.fromInt(interestPeriodTypeValue);
|
||||
}
|
||||
|
||||
SavingsInterestCalculationType interestCalculationType = null;
|
||||
@@ -61,14 +54,13 @@ public class SavingsProductAssembler {
|
||||
final BigDecimal minRequiredOpeningBalance = command.bigDecimalValueOfParameterNamed(minRequiredOpeningBalanceParamName);
|
||||
|
||||
final Integer lockinPeriodFrequency = command.integerValueOfParameterNamed(lockinPeriodFrequencyParamName);
|
||||
PeriodFrequencyType lockinPeriodFrequencyType = null;
|
||||
SavingsPeriodFrequencyType lockinPeriodFrequencyType = null;
|
||||
final Integer lockinPeriodFrequencyTypeValue = command.integerValueOfParameterNamed(lockinPeriodFrequencyTypeParamName);
|
||||
if (lockinPeriodFrequencyTypeValue != null) {
|
||||
lockinPeriodFrequencyType = PeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
|
||||
lockinPeriodFrequencyType = SavingsPeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
|
||||
}
|
||||
|
||||
return SavingsProduct.createNew(name, description, currency, interestRate, interestRatePeriodFrequencyType, interestPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType);
|
||||
return SavingsProduct.createNew(name, description, currency, interestRate, interestPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
}
|
||||
}
|
||||
+33
-47
@@ -27,9 +27,9 @@ import org.mifosplatform.portfolio.savings.data.SavingsAccountSummaryData;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionEnumData;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savings.exception.SavingsAccountNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -103,10 +103,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
sqlBuilder.append("sa.currency_code as currencyCode, sa.currency_digits as currencyDigits, ");
|
||||
sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
|
||||
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
|
||||
sqlBuilder.append("sa.nominal_interest_rate_per_period as interestRate, ");
|
||||
sqlBuilder.append("sa.nominal_interest_rate_period_frequency_enum as interestRatePeriodFrequencyType, ");
|
||||
sqlBuilder.append("sa.annual_nominal_interest_rate as annualInterestRate, ");
|
||||
sqlBuilder.append("sa.interest_period_enum as interestPeriodType, ");
|
||||
sqlBuilder.append("sa.nominal_annual_interest_rate as nominalAnnualInterestRate, ");
|
||||
sqlBuilder.append("sa.interest_compounding_period_enum as interestCompoundingPeriodType, ");
|
||||
sqlBuilder.append("sa.interest_calculation_type_enum as interestCalculationType, ");
|
||||
sqlBuilder.append("sa.interest_calculation_days_in_year_type_enum as interestCalculationDaysInYearType, ");
|
||||
sqlBuilder.append("sa.min_required_opening_balance as minRequiredOpeningBalance, ");
|
||||
@@ -158,20 +156,16 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
|
||||
final BigDecimal interestRate = rs.getBigDecimal("interestRate");
|
||||
final SavingsPeriodFrequencyType interestRatePeriodType = SavingsPeriodFrequencyType.fromInt(JdbcSupport.getInteger(rs,
|
||||
"interestRatePeriodFrequencyType"));
|
||||
final EnumOptionData interestRatePeriodFrequencyType = SavingsEnumerations
|
||||
.interestRatePeriodFrequencyType(interestRatePeriodType);
|
||||
final BigDecimal annualInterestRate = rs.getBigDecimal("annualInterestRate");
|
||||
final BigDecimal nominalAnnualInterestRate = rs.getBigDecimal("nominalAnnualInterestRate");
|
||||
|
||||
EnumOptionData interestPeriodType = SavingsEnumerations.interestPeriodType(SavingsInterestPeriodType.fromInt(JdbcSupport
|
||||
.getInteger(rs, "interestPeriodType")));
|
||||
final EnumOptionData interestCompoundingPeriodType = SavingsEnumerations
|
||||
.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.fromInt(JdbcSupport.getInteger(rs,
|
||||
"interestCompoundingPeriodType")));
|
||||
|
||||
EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(SavingsInterestCalculationType
|
||||
final EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(SavingsInterestCalculationType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestCalculationType")));
|
||||
|
||||
EnumOptionData interestCalculationDaysInYearType = SavingsEnumerations
|
||||
final EnumOptionData interestCalculationDaysInYearType = SavingsEnumerations
|
||||
.interestCalculationDaysInYearType(SavingsInterestCalculationDaysInYearType.fromInt(JdbcSupport.getInteger(rs,
|
||||
"interestCalculationDaysInYearType")));
|
||||
|
||||
@@ -194,10 +188,11 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
final SavingsAccountSummaryData summary = new SavingsAccountSummaryData(currency, totalDeposits, totalWithdrawals,
|
||||
totalInterestEarned, totalInterestPosted, accountBalance);
|
||||
|
||||
return SavingsAccountData.instance(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName,
|
||||
productId, productName, currency, interestRate, interestRatePeriodFrequencyType, annualInterestRate,
|
||||
interestPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType, summary);
|
||||
return SavingsAccountData
|
||||
.instance(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName, productId,
|
||||
productName, currency, nominalAnnualInterestRate, interestCompoundingPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
|
||||
summary);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,11 +220,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
final String sql = "select " + mapper.schema() + " where sp.id = ?";
|
||||
template = this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { productId });
|
||||
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveInterestRatePeriodFrequencyTypeOptions();
|
||||
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveInterestPeriodTypeOptions();
|
||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveCompoundingInterestPeriodTypeOptions();
|
||||
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveInterestCalculationTypeOptions();
|
||||
@@ -241,9 +233,9 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
.retrieveLockinPeriodFrequencyTypeOptions();
|
||||
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||
|
||||
template = SavingsAccountData.withTemplateOptions(template, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
interestPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions, transactions);
|
||||
template = SavingsAccountData.withTemplateOptions(template, productOptions, interestCompoundingPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
|
||||
transactions);
|
||||
} else {
|
||||
|
||||
String clientName = null;
|
||||
@@ -258,16 +250,15 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
|
||||
template = SavingsAccountData.withClientTemplate(clientId, clientName, groupId, groupName);
|
||||
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||
|
||||
template = SavingsAccountData.withTemplateOptions(template, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
interestPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions, transactions);
|
||||
template = SavingsAccountData.withTemplateOptions(template, productOptions, interestCompoundingPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
|
||||
transactions);
|
||||
}
|
||||
|
||||
return template;
|
||||
@@ -398,9 +389,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
sqlBuilder.append("sp.currency_code as currencyCode, sp.currency_digits as currencyDigits, ");
|
||||
sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
|
||||
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
|
||||
sqlBuilder.append("sp.nominal_interest_rate_per_period as interestRate, ");
|
||||
sqlBuilder.append("sp.nominal_interest_rate_period_frequency_enum as interestRatePeriodFrequencyType, ");
|
||||
sqlBuilder.append("sp.interest_period_enum as interestPeriodType, ");
|
||||
sqlBuilder.append("sp.nominal_annual_interest_rate as nominalAnnualIterestRate, ");
|
||||
sqlBuilder.append("sp.interest_compounding_period_enum as interestCompoundingPeriodType, ");
|
||||
sqlBuilder.append("sp.interest_calculation_type_enum as interestCalculationType, ");
|
||||
sqlBuilder.append("sp.interest_calculation_days_in_year_type_enum as interestCalculationDaysInYearType, ");
|
||||
sqlBuilder.append("sp.min_required_opening_balance as minRequiredOpeningBalance, ");
|
||||
@@ -430,15 +420,10 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
|
||||
final BigDecimal interestRate = rs.getBigDecimal("interestRate");
|
||||
final SavingsPeriodFrequencyType interestRatePeriodType = SavingsPeriodFrequencyType.fromInt(JdbcSupport.getInteger(rs,
|
||||
"interestRatePeriodFrequencyType"));
|
||||
final EnumOptionData interestRatePeriodFrequencyType = SavingsEnumerations
|
||||
.interestRatePeriodFrequencyType(interestRatePeriodType);
|
||||
final BigDecimal annualInterestRate = null;
|
||||
final BigDecimal nominalAnnualIterestRate = rs.getBigDecimal("nominalAnnualIterestRate");
|
||||
|
||||
EnumOptionData interestPeriodType = SavingsEnumerations.interestPeriodType(SavingsInterestPeriodType.fromInt(JdbcSupport
|
||||
.getInteger(rs, "interestPeriodType")));
|
||||
EnumOptionData interestPeriodType = SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestCompoundingPeriodType")));
|
||||
|
||||
EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(SavingsInterestCalculationType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestCalculationType")));
|
||||
@@ -474,10 +459,11 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
final SavingsAccountStatusEnumData status = null;
|
||||
final LocalDate activationDate = null;
|
||||
final SavingsAccountSummaryData summary = null;
|
||||
return SavingsAccountData.instance(null, null, null, status, activationDate, groupId, groupName, clientId, clientName,
|
||||
productId, productName, currency, interestRate, interestRatePeriodFrequencyType, annualInterestRate,
|
||||
interestPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType, summary);
|
||||
return SavingsAccountData
|
||||
.instance(null, null, null, status, activationDate, groupId, groupName, clientId, clientName, productId, productName,
|
||||
currency, nominalAnnualIterestRate, interestPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
|
||||
summary);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -17,6 +17,7 @@ import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator;
|
||||
import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory;
|
||||
@@ -321,7 +322,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(savingsId);
|
||||
|
||||
account.calculateInterest();
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.calculateInterest(today);
|
||||
this.savingAccountRepository.save(account);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
|
||||
+1
-3
@@ -6,11 +6,9 @@ import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
|
||||
public interface SavingsDropdownReadPlatformService {
|
||||
|
||||
Collection<EnumOptionData> retrieveInterestRatePeriodFrequencyTypeOptions();
|
||||
|
||||
Collection<EnumOptionData> retrieveLockinPeriodFrequencyTypeOptions();
|
||||
|
||||
Collection<EnumOptionData> retrieveInterestPeriodTypeOptions();
|
||||
Collection<EnumOptionData> retrieveCompoundingInterestPeriodTypeOptions();
|
||||
|
||||
Collection<EnumOptionData> retrieveInterestCalculationTypeOptions();
|
||||
|
||||
|
||||
+10
-19
@@ -5,25 +5,15 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class SavingsDropdownReadPlatformServiceImpl implements SavingsDropdownReadPlatformService {
|
||||
|
||||
@Override
|
||||
public List<EnumOptionData> retrieveInterestRatePeriodFrequencyTypeOptions() {
|
||||
List<EnumOptionData> allowedInterestRatePeriodFrequencyTypeOptions = Arrays.asList( //
|
||||
SavingsEnumerations.interestRatePeriodFrequencyType(SavingsPeriodFrequencyType.MONTHS), //
|
||||
SavingsEnumerations.interestRatePeriodFrequencyType(SavingsPeriodFrequencyType.YEARS) //
|
||||
);
|
||||
|
||||
return allowedInterestRatePeriodFrequencyTypeOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EnumOptionData> retrieveLockinPeriodFrequencyTypeOptions() {
|
||||
List<EnumOptionData> allowedLockinPeriodFrequencyTypeOptions = Arrays.asList( //
|
||||
@@ -37,15 +27,16 @@ public class SavingsDropdownReadPlatformServiceImpl implements SavingsDropdownRe
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<EnumOptionData> retrieveInterestPeriodTypeOptions() {
|
||||
public Collection<EnumOptionData> retrieveCompoundingInterestPeriodTypeOptions() {
|
||||
List<EnumOptionData> allowedOptions = Arrays.asList( //
|
||||
SavingsEnumerations.interestPeriodType(SavingsInterestPeriodType.DAILY), //
|
||||
SavingsEnumerations.interestPeriodType(SavingsInterestPeriodType.WEEKLY), //
|
||||
SavingsEnumerations.interestPeriodType(SavingsInterestPeriodType.BIWEEKLY), //
|
||||
SavingsEnumerations.interestPeriodType(SavingsInterestPeriodType.MONTHLY), //
|
||||
SavingsEnumerations.interestPeriodType(SavingsInterestPeriodType.QUATERLY), //
|
||||
SavingsEnumerations.interestPeriodType(SavingsInterestPeriodType.SEMIANNUAL), //
|
||||
SavingsEnumerations.interestPeriodType(SavingsInterestPeriodType.ANNUAL) //
|
||||
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.DAILY), //
|
||||
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.WEEKLY), //
|
||||
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.BIWEEKLY), //
|
||||
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.MONTHLY), //
|
||||
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.QUATERLY), //
|
||||
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.BI_ANNUAL), //
|
||||
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.ANNUAL), //
|
||||
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.NO_COMPOUNDING_SIMPLE_INTEREST) //
|
||||
);
|
||||
|
||||
return allowedOptions;
|
||||
|
||||
+25
-51
@@ -10,44 +10,13 @@ import org.mifosplatform.portfolio.savings.data.SavingsAccountStatusEnumData;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionEnumData;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountStatusType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransactionType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType;
|
||||
|
||||
public class SavingsEnumerations {
|
||||
|
||||
public static EnumOptionData interestRatePeriodFrequencyType(final int id) {
|
||||
return interestRatePeriodFrequencyType(SavingsPeriodFrequencyType.fromInt(id));
|
||||
}
|
||||
|
||||
public static EnumOptionData interestRatePeriodFrequencyType(final SavingsPeriodFrequencyType type) {
|
||||
final String codePrefix = "savings.interest.rate.";
|
||||
EnumOptionData optionData = new EnumOptionData(SavingsPeriodFrequencyType.INVALID.getValue().longValue(),
|
||||
SavingsPeriodFrequencyType.INVALID.getCode(), "Invalid");
|
||||
switch (type) {
|
||||
case INVALID:
|
||||
break;
|
||||
case DAYS:
|
||||
optionData = new EnumOptionData(SavingsPeriodFrequencyType.DAYS.getValue().longValue(), codePrefix
|
||||
+ SavingsPeriodFrequencyType.DAYS.getCode(), "Per day");
|
||||
break;
|
||||
case WEEKS:
|
||||
optionData = new EnumOptionData(SavingsPeriodFrequencyType.WEEKS.getValue().longValue(), codePrefix
|
||||
+ SavingsPeriodFrequencyType.WEEKS.getCode(), "Per week");
|
||||
break;
|
||||
case MONTHS:
|
||||
optionData = new EnumOptionData(SavingsPeriodFrequencyType.MONTHS.getValue().longValue(), codePrefix
|
||||
+ SavingsPeriodFrequencyType.MONTHS.getCode(), "Per month");
|
||||
break;
|
||||
case YEARS:
|
||||
optionData = new EnumOptionData(SavingsPeriodFrequencyType.YEARS.getValue().longValue(), codePrefix
|
||||
+ SavingsPeriodFrequencyType.YEARS.getCode(), "Per year");
|
||||
break;
|
||||
}
|
||||
return optionData;
|
||||
}
|
||||
|
||||
public static EnumOptionData lockinPeriodFrequencyType(final int id) {
|
||||
return lockinPeriodFrequencyType(SavingsPeriodFrequencyType.fromInt(id));
|
||||
}
|
||||
@@ -141,45 +110,50 @@ public class SavingsEnumerations {
|
||||
}
|
||||
|
||||
public static EnumOptionData interestPeriodType(final Integer type) {
|
||||
return interestPeriodType(SavingsInterestPeriodType.fromInt(type));
|
||||
return compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.fromInt(type));
|
||||
}
|
||||
|
||||
public static EnumOptionData interestPeriodType(final SavingsInterestPeriodType type) {
|
||||
public static EnumOptionData compoundingInterestPeriodType(final SavingsCompoundingInterestPeriodType type) {
|
||||
|
||||
final String codePrefix = "savings.interest.period.";
|
||||
EnumOptionData optionData = new EnumOptionData(SavingsInterestPeriodType.INVALID.getValue().longValue(),
|
||||
SavingsInterestPeriodType.INVALID.getCode(), "Invalid");
|
||||
EnumOptionData optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.INVALID.getValue().longValue(),
|
||||
SavingsCompoundingInterestPeriodType.INVALID.getCode(), "Invalid");
|
||||
|
||||
switch (type) {
|
||||
case INVALID:
|
||||
break;
|
||||
case DAILY:
|
||||
optionData = new EnumOptionData(SavingsInterestPeriodType.DAILY.getValue().longValue(), codePrefix
|
||||
+ SavingsInterestPeriodType.DAILY.getCode(), "Daily");
|
||||
optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.DAILY.getValue().longValue(), codePrefix
|
||||
+ SavingsCompoundingInterestPeriodType.DAILY.getCode(), "Daily");
|
||||
break;
|
||||
case WEEKLY:
|
||||
optionData = new EnumOptionData(SavingsInterestPeriodType.WEEKLY.getValue().longValue(), codePrefix
|
||||
+ SavingsInterestPeriodType.WEEKLY.getCode(), "Weekly");
|
||||
optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.WEEKLY.getValue().longValue(), codePrefix
|
||||
+ SavingsCompoundingInterestPeriodType.WEEKLY.getCode(), "Weekly");
|
||||
break;
|
||||
case BIWEEKLY:
|
||||
optionData = new EnumOptionData(SavingsInterestPeriodType.BIWEEKLY.getValue().longValue(), codePrefix
|
||||
+ SavingsInterestPeriodType.BIWEEKLY.getCode(), "Bi-Weekly");
|
||||
optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.BIWEEKLY.getValue().longValue(), codePrefix
|
||||
+ SavingsCompoundingInterestPeriodType.BIWEEKLY.getCode(), "Bi-Weekly");
|
||||
break;
|
||||
case MONTHLY:
|
||||
optionData = new EnumOptionData(SavingsInterestPeriodType.MONTHLY.getValue().longValue(), codePrefix
|
||||
+ SavingsInterestPeriodType.MONTHLY.getCode(), "Monthly");
|
||||
optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.MONTHLY.getValue().longValue(), codePrefix
|
||||
+ SavingsCompoundingInterestPeriodType.MONTHLY.getCode(), "Monthly");
|
||||
break;
|
||||
case QUATERLY:
|
||||
optionData = new EnumOptionData(SavingsInterestPeriodType.QUATERLY.getValue().longValue(), codePrefix
|
||||
+ SavingsInterestPeriodType.QUATERLY.getCode(), "Quarterly");
|
||||
optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.QUATERLY.getValue().longValue(), codePrefix
|
||||
+ SavingsCompoundingInterestPeriodType.QUATERLY.getCode(), "Quarterly");
|
||||
break;
|
||||
case SEMIANNUAL:
|
||||
optionData = new EnumOptionData(SavingsInterestPeriodType.SEMIANNUAL.getValue().longValue(), codePrefix
|
||||
+ SavingsInterestPeriodType.SEMIANNUAL.getCode(), "Semi-Annual");
|
||||
case BI_ANNUAL:
|
||||
optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.BI_ANNUAL.getValue().longValue(), codePrefix
|
||||
+ SavingsCompoundingInterestPeriodType.BI_ANNUAL.getCode(), "Semi-Annual");
|
||||
break;
|
||||
case ANNUAL:
|
||||
optionData = new EnumOptionData(SavingsInterestPeriodType.ANNUAL.getValue().longValue(), codePrefix
|
||||
+ SavingsInterestPeriodType.ANNUAL.getCode(), "Annually");
|
||||
optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.ANNUAL.getValue().longValue(), codePrefix
|
||||
+ SavingsCompoundingInterestPeriodType.ANNUAL.getCode(), "Annually");
|
||||
break;
|
||||
case NO_COMPOUNDING_SIMPLE_INTEREST:
|
||||
optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.NO_COMPOUNDING_SIMPLE_INTEREST.getValue().longValue(),
|
||||
codePrefix + SavingsCompoundingInterestPeriodType.NO_COMPOUNDING_SIMPLE_INTEREST.getCode(),
|
||||
"No Compounding - Simple Interest");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+10
-13
@@ -16,9 +16,9 @@ import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSourc
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savings.exception.SavingsProductNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -80,9 +80,8 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
|
||||
sqlBuilder.append("sp.currency_code as currencyCode, sp.currency_digits as currencyDigits, ");
|
||||
sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
|
||||
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
|
||||
sqlBuilder.append("sp.nominal_interest_rate_per_period as interestRate, ");
|
||||
sqlBuilder.append("sp.nominal_interest_rate_period_frequency_enum as interestRatePeriodFrequencyType, ");
|
||||
sqlBuilder.append("sp.interest_period_enum as interestPeriodType, ");
|
||||
sqlBuilder.append("sp.nominal_annual_interest_rate as nominalAnnualInterestRate, ");
|
||||
sqlBuilder.append("sp.interest_compounding_period_enum as compoundingInterestPeriodType, ");
|
||||
sqlBuilder.append("sp.interest_calculation_type_enum as interestCalculationType, ");
|
||||
sqlBuilder.append("sp.interest_calculation_days_in_year_type_enum as interestCalculationDaysInYearType, ");
|
||||
sqlBuilder.append("sp.min_required_opening_balance as minRequiredOpeningBalance, ");
|
||||
@@ -113,13 +112,11 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
|
||||
|
||||
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
BigDecimal interestRate = rs.getBigDecimal("interestRate");
|
||||
final BigDecimal nominalAnnualInterestRate = rs.getBigDecimal("nominalAnnualInterestRate");
|
||||
|
||||
EnumOptionData interestRatePeriodFrequencyType = SavingsEnumerations.interestRatePeriodFrequencyType(SavingsPeriodFrequencyType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestRatePeriodFrequencyType")));
|
||||
|
||||
EnumOptionData interestPeriodType = SavingsEnumerations.interestPeriodType(SavingsInterestPeriodType.fromInt(JdbcSupport
|
||||
.getInteger(rs, "interestPeriodType")));
|
||||
EnumOptionData compoundingInterestPeriodType = SavingsEnumerations
|
||||
.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.fromInt(JdbcSupport.getInteger(rs,
|
||||
"compoundingInterestPeriodType")));
|
||||
|
||||
EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(SavingsInterestCalculationType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestCalculationType")));
|
||||
@@ -142,9 +139,9 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
|
||||
.fromInt(lockinPeriodFrequencyTypeValue));
|
||||
}
|
||||
|
||||
return SavingsProductData.instance(id, name, description, currency, interestRate, interestRatePeriodFrequencyType,
|
||||
interestPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
return SavingsProductData.instance(id, name, description, currency, nominalAnnualInterestRate, compoundingInterestPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user