MIFOSX-250: wip on interest compounding and posting

This commit is contained in:
Keith Woodlock
2013-04-06 11:41:14 +01:00
parent 8730976f99
commit 14aa62073e
27 changed files with 590 additions and 147 deletions
@@ -0,0 +1,12 @@
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`)
VALUES
('transaction_savings', 'POSTINTEREST_SAVINGSACCOUNT', 'SAVINGSACCOUNT', 'POSTINTEREST', '1'),
('transaction_savings', 'POSTINTEREST_SAVINGSACCOUNT_CHECKER', 'SAVINGSACCOUNT', 'POSTINTEREST', '0');
ALTER TABLE `m_savings_product`
ADD COLUMN `interest_posting_period_enum` SMALLINT(5) NOT NULL DEFAULT 4 AFTER `interest_compounding_period_enum`;
ALTER TABLE `m_savings_account`
ADD COLUMN `interest_posting_period_enum` SMALLINT(5) NOT NULL DEFAULT 4 AFTER `interest_compounding_period_enum`;
@@ -450,6 +450,10 @@ public class CommandWrapper {
return this.actionName.equalsIgnoreCase("CALCULATEINTEREST") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT"); return this.actionName.equalsIgnoreCase("CALCULATEINTEREST") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
} }
public boolean isSavingsAccountInterestPosting() {
return this.actionName.equalsIgnoreCase("POSTINTEREST") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
}
public boolean isCalendarResource() { public boolean isCalendarResource() {
return this.entityName.equalsIgnoreCase("CALENDAR"); return this.entityName.equalsIgnoreCase("CALENDAR");
} }
@@ -717,11 +717,20 @@ public class CommandWrapperBuilder {
this.actionName = "CALCULATEINTEREST"; this.actionName = "CALCULATEINTEREST";
this.entityName = "SAVINGSACCOUNT"; this.entityName = "SAVINGSACCOUNT";
this.savingsId = accountId; this.savingsId = accountId;
this.entityId = null; this.entityId = accountId;
this.href = "/savingsaccounts/" + accountId + "?command=calculateInterest"; this.href = "/savingsaccounts/" + accountId + "?command=calculateInterest";
return this; return this;
} }
public CommandWrapperBuilder savingsAccountInterestPosting(final Long accountId) {
this.actionName = "POSTINTEREST";
this.entityName = "SAVINGSACCOUNT";
this.savingsId = accountId;
this.entityId = accountId;
this.href = "/savingsaccounts/" + accountId + "?command=postInterest";
return this;
}
public CommandWrapperBuilder createCalendar(final String supportedEntityType, final Long supportedEntityId) { public CommandWrapperBuilder createCalendar(final String supportedEntityType, final Long supportedEntityId) {
this.actionName = "CREATE"; this.actionName = "CREATE";
this.entityName = "CALENDAR"; this.entityName = "CALENDAR";
@@ -370,6 +370,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
handler = applicationContext.getBean("activateSavingsAccountCommandHandler", NewCommandSourceHandler.class); handler = applicationContext.getBean("activateSavingsAccountCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isSavingsAccountInterestCalculation()) { } else if (wrapper.isSavingsAccountInterestCalculation()) {
handler = applicationContext.getBean("calculateInterestSavingsAccountCommandHandler", NewCommandSourceHandler.class); handler = applicationContext.getBean("calculateInterestSavingsAccountCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isSavingsAccountInterestPosting()) {
handler = applicationContext.getBean("postInterestSavingsAccountCommandHandler", NewCommandSourceHandler.class);
} else { } else {
throw new UnsupportedCommandException(wrapper.commandName()); throw new UnsupportedCommandException(wrapper.commandName());
} }
@@ -192,7 +192,7 @@ public class DataValidatorBuilder {
return this; return this;
} }
public DataValidatorBuilder inOfTheseValues(final Object... values) { public DataValidatorBuilder isOneOfTheseValues(final Object... values) {
if (value == null && ignoreNullValue) { return this; } if (value == null && ignoreNullValue) { return this; }
if (value != null) { if (value != null) {
@@ -9,10 +9,12 @@ public class UnrecognizedQueryParamException extends RuntimeException {
private final String queryParamKey; private final String queryParamKey;
private final String queryParamValue; private final String queryParamValue;
private final Object[] supportedParams;
public UnrecognizedQueryParamException(final String queryParamKey, final String queryParamValue) { public UnrecognizedQueryParamException(final String queryParamKey, final String queryParamValue, final Object... supportedParams) {
this.queryParamKey = queryParamKey; this.queryParamKey = queryParamKey;
this.queryParamValue = queryParamValue; this.queryParamValue = queryParamValue;
this.supportedParams = supportedParams;
} }
public String getQueryParamKey() { public String getQueryParamKey() {
@@ -22,4 +24,8 @@ public class UnrecognizedQueryParamException extends RuntimeException {
public String getQueryParamValue() { public String getQueryParamValue() {
return queryParamValue; return queryParamValue;
} }
public Object[] getSupportedParams() {
return this.supportedParams;
}
} }
@@ -33,22 +33,25 @@ import org.springframework.stereotype.Component;
public class UnrecognizedQueryParamExceptionMapper implements ExceptionMapper<UnrecognizedQueryParamException> { public class UnrecognizedQueryParamExceptionMapper implements ExceptionMapper<UnrecognizedQueryParamException> {
@Override @Override
public Response toResponse(UnrecognizedQueryParamException exception) { public Response toResponse(final UnrecognizedQueryParamException exception) {
String parameterName = exception.getQueryParamKey(); final String parameterName = exception.getQueryParamKey();
String parameterValue = exception.getQueryParamValue(); final String parameterValue = exception.getQueryParamValue();
StringBuilder validationErrorCode = new StringBuilder("error.msg.query.parameter.value.unsupported"); final StringBuilder validationErrorCode = new StringBuilder("error.msg.query.parameter.value.unsupported");
StringBuilder defaultEnglishMessage = new StringBuilder("The query parameter ").append(parameterName) final StringBuilder defaultEnglishMessage = new StringBuilder("The query parameter ") //
.append(" has an unsupported value of: ").append(parameterValue); .append(parameterName) //
ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), .append(" has an unsupported value of: ") //
parameterName, parameterName, parameterValue); .append(parameterValue);
List<ApiParameterError> errors = new ArrayList<ApiParameterError>(); final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(),
parameterName, parameterName, parameterValue, exception.getSupportedParams());
final List<ApiParameterError> errors = new ArrayList<ApiParameterError>();
errors.add(error); errors.add(error);
ApiGlobalErrorResponse invalidParameterError = ApiGlobalErrorResponse.badClientRequest("validation.msg.validation.errors.exist", final ApiGlobalErrorResponse invalidParameterError = ApiGlobalErrorResponse.badClientRequest(
"Validation errors exist.", errors); "validation.msg.validation.errors.exist", "Validation errors exist.", errors);
return Response.status(Status.BAD_REQUEST).entity(invalidParameterError).type(MediaType.APPLICATION_JSON).build(); return Response.status(Status.BAD_REQUEST).entity(invalidParameterError).type(MediaType.APPLICATION_JSON).build();
} }
@@ -141,6 +141,7 @@ public class SavingsAccountsApiResource {
Collection<SavingsAccountTransactionData> transactions = null; Collection<SavingsAccountTransactionData> transactions = null;
Collection<SavingsProductData> productOptions = null; Collection<SavingsProductData> productOptions = null;
Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null; Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
Collection<EnumOptionData> interestCompoundingPostingTypeOptions = null;
Collection<EnumOptionData> interestCalculationTypeOptions = null; Collection<EnumOptionData> interestCalculationTypeOptions = null;
Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null; Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null; Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
@@ -166,12 +167,14 @@ public class SavingsAccountsApiResource {
if (settings.isTemplate()) { if (settings.isTemplate()) {
productOptions = this.savingsProductReadPlatformService.retrieveAllForLookup(); productOptions = this.savingsProductReadPlatformService.retrieveAllForLookup();
interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService.retrieveCompoundingInterestPeriodTypeOptions(); interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService.retrieveCompoundingInterestPeriodTypeOptions();
interestCompoundingPostingTypeOptions = this.dropdownReadPlatformService.retrieveInterestPostingPeriodTypeOptions();
interestCalculationTypeOptions = this.dropdownReadPlatformService.retrieveInterestCalculationTypeOptions(); interestCalculationTypeOptions = this.dropdownReadPlatformService.retrieveInterestCalculationTypeOptions();
lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveLockinPeriodFrequencyTypeOptions(); lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveLockinPeriodFrequencyTypeOptions();
} }
return SavingsAccountData.withTemplateOptions(savingsAccount, productOptions, interestCompoundingPeriodTypeOptions, return SavingsAccountData.withTemplateOptions(savingsAccount, productOptions, interestCompoundingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions); interestCompoundingPostingTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, transactions);
} }
@PUT @PUT
@@ -204,11 +207,15 @@ public class SavingsAccountsApiResource {
} else if (is(commandParam, "calculateInterest")) { } else if (is(commandParam, "calculateInterest")) {
final CommandWrapper commandRequest = builder.savingsAccountInterestCalculation(accountId).build(); final CommandWrapper commandRequest = builder.savingsAccountInterestCalculation(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "postInterest")) {
final CommandWrapper commandRequest = builder.savingsAccountInterestPosting(accountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} }
if (result == null) { if (result == null) {
// FIXME - KW - handle blank command param use case //
throw new UnrecognizedQueryParamException("command", commandParam); throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "activate", "calculateInterest",
"postInterest" });
} }
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
@@ -32,8 +32,8 @@ public class SavingsApiConstants {
public static final String currencyCodeParamName = "currencyCode"; public static final String currencyCodeParamName = "currencyCode";
public static final String digitsAfterDecimalParamName = "digitsAfterDecimal"; public static final String digitsAfterDecimalParamName = "digitsAfterDecimal";
public static final String nominalAnnualInterestRateParamName = "nominalAnnualInterestRate"; public static final String nominalAnnualInterestRateParamName = "nominalAnnualInterestRate";
public static final String interestCompoundingPeriodTypeParamName = "interestCompoundingPeriodType"; public static final String interestCompoundingPeriodTypeParamName = "interestCompoundingPeriodType";
public static final String interestPostingPeriodTypeParamName = "interestPostingPeriodType";
public static final String interestCalculationTypeParamName = "interestCalculationType"; public static final String interestCalculationTypeParamName = "interestCalculationType";
public static final String interestCalculationDaysInYearTypeParamName = "interestCalculationDaysInYearType"; public static final String interestCalculationDaysInYearTypeParamName = "interestCalculationDaysInYearType";
public static final String minRequiredOpeningBalanceParamName = "minRequiredOpeningBalance"; public static final String minRequiredOpeningBalanceParamName = "minRequiredOpeningBalance";
@@ -46,8 +46,9 @@ public class SavingsApiConstants {
public static final Set<String> SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName, public static final Set<String> SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
nameParamName, descriptionParamName, currencyCodeParamName, digitsAfterDecimalParamName, nominalAnnualInterestRateParamName, nameParamName, descriptionParamName, currencyCodeParamName, digitsAfterDecimalParamName, nominalAnnualInterestRateParamName,
interestCompoundingPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName, interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName, interestCalculationTypeParamName,
minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName)); interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName,
lockinPeriodFrequencyTypeParamName));
/** /**
* These parameters will match the class level parameters of * These parameters will match the class level parameters of
@@ -56,15 +57,17 @@ public class SavingsApiConstants {
*/ */
public static final Set<String> SAVINGS_PRODUCT_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName, public static final Set<String> SAVINGS_PRODUCT_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName,
nameParamName, descriptionParamName, "currency", digitsAfterDecimalParamName, nominalAnnualInterestRateParamName, nameParamName, descriptionParamName, "currency", digitsAfterDecimalParamName, nominalAnnualInterestRateParamName,
interestCompoundingPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName, interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName, interestCalculationTypeParamName,
minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName, "currencyOptions", interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName,
"interestRatePeriodFrequencyTypeOptions", "lockinPeriodFrequencyTypeOptions")); lockinPeriodFrequencyTypeParamName, "currencyOptions", "interestCompoundingPeriodTypeOptions",
"interestPostingPeriodTypeOptions", "interestCalculationTypeOptions", "interestCalculationDaysInYearTypeOptions",
"lockinPeriodFrequencyTypeOptions"));
public static final Set<String> SAVINGS_ACCOUNT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName, public static final Set<String> SAVINGS_ACCOUNT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, accountNoParamName, externalIdParamName, clientIdParamName, groupIdParamName, productIdParamName, dateFormatParamName, accountNoParamName, externalIdParamName, clientIdParamName, groupIdParamName, productIdParamName,
activeParamName, activationDateParamName, nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName, activeParamName, activationDateParamName, nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName,
interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName, interestPostingPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName,
lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName)); minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName));
/** /**
* These parameters will match the class level parameters of * These parameters will match the class level parameters of
@@ -74,10 +77,10 @@ public class SavingsApiConstants {
public static final Set<String> SAVINGS_ACCOUNT_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName, public static final Set<String> SAVINGS_ACCOUNT_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName,
accountNoParamName, externalIdParamName, statusParamName, activationDateParamName, clientIdParamName, "clientName", accountNoParamName, externalIdParamName, statusParamName, activationDateParamName, clientIdParamName, "clientName",
groupIdParamName, "groupName", "savingsProductId", "savingsProductName", "currency", nominalAnnualInterestRateParamName, groupIdParamName, "groupName", "savingsProductId", "savingsProductName", "currency", nominalAnnualInterestRateParamName,
interestCompoundingPeriodTypeParamName, interestCalculationTypeParamName, interestCompoundingPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName,
interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName, "summary",
lockinPeriodFrequencyTypeParamName, "summary", "transactions", "productOptions", "interestRatePeriodFrequencyTypeOptions", "transactions", "productOptions", "interestCompoundingPeriodTypeOptions", "interestPostingPeriodTypeOptions",
"lockinPeriodFrequencyTypeOptions")); "interestCalculationTypeOptions", "interestCalculationDaysInYearTypeOptions", "lockinPeriodFrequencyTypeOptions"));
public static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList( public static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
localeParamName, dateFormatParamName, transactionDateParamName, transactionAmountParamName)); localeParamName, dateFormatParamName, transactionDateParamName, transactionAmountParamName));
@@ -35,6 +35,7 @@ import org.mifosplatform.portfolio.savings.data.SavingsProductData;
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType; import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType; import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType; import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPostingPeriodType;
import org.mifosplatform.portfolio.savings.service.SavingsDropdownReadPlatformService; import org.mifosplatform.portfolio.savings.service.SavingsDropdownReadPlatformService;
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations; import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
import org.mifosplatform.portfolio.savings.service.SavingsProductReadPlatformService; import org.mifosplatform.portfolio.savings.service.SavingsProductReadPlatformService;
@@ -146,9 +147,12 @@ public class SavingsProductsApiResource {
private SavingsProductData handleTemplateRelatedData(final SavingsProductData savingsProduct) { private SavingsProductData handleTemplateRelatedData(final SavingsProductData savingsProduct) {
final EnumOptionData interestPeriodType = SavingsEnumerations final EnumOptionData interestCompoundingPeriodType = SavingsEnumerations
.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.DAILY); .compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.DAILY);
final EnumOptionData interestPostingPeriodType = SavingsEnumerations
.interestPostingPeriodType(SavingsInterestPostingPeriodType.MONTHLY);
final EnumOptionData interestCalculationType = SavingsEnumerations final EnumOptionData interestCalculationType = SavingsEnumerations
.interestCalculationType(SavingsInterestCalculationType.DAILY_BALANCE); .interestCalculationType(SavingsInterestCalculationType.DAILY_BALANCE);
@@ -161,9 +165,12 @@ public class SavingsProductsApiResource {
currency = new ArrayList<CurrencyData>(currencyOptions).get(0); currency = new ArrayList<CurrencyData>(currencyOptions).get(0);
} }
final Collection<EnumOptionData> interestPeriodTypeOptions = this.dropdownReadPlatformService final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService
.retrieveCompoundingInterestPeriodTypeOptions(); .retrieveCompoundingInterestPeriodTypeOptions();
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = this.dropdownReadPlatformService
.retrieveInterestPostingPeriodTypeOptions();
final Collection<EnumOptionData> interestCalculationTypeOptions = this.dropdownReadPlatformService final Collection<EnumOptionData> interestCalculationTypeOptions = this.dropdownReadPlatformService
.retrieveInterestCalculationTypeOptions(); .retrieveInterestCalculationTypeOptions();
@@ -175,12 +182,14 @@ public class SavingsProductsApiResource {
SavingsProductData savingsProductToReturn = null; SavingsProductData savingsProductToReturn = null;
if (savingsProduct != null) { if (savingsProduct != null) {
savingsProductToReturn = SavingsProductData.withTemplate(savingsProduct, currencyOptions, interestPeriodTypeOptions, savingsProductToReturn = SavingsProductData.withTemplate(savingsProduct, currencyOptions, interestCompoundingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions); interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions);
} else { } else {
savingsProductToReturn = SavingsProductData.template(currency, interestPeriodType, interestCalculationType, savingsProductToReturn = SavingsProductData.template(currency, interestCompoundingPeriodType, interestPostingPeriodType,
interestCalculationDaysInYearType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationType, interestCalculationDaysInYearType, currencyOptions, interestCompoundingPeriodTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions); interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions);
} }
return savingsProductToReturn; return savingsProductToReturn;
@@ -15,7 +15,6 @@ import org.mifosplatform.organisation.monetary.data.CurrencyData;
/** /**
* Immutable data object representing a savings account. * Immutable data object representing a savings account.
*/ */
@SuppressWarnings("unused")
public class SavingsAccountData { public class SavingsAccountData {
private final Long id; private final Long id;
@@ -32,6 +31,7 @@ public class SavingsAccountData {
private final CurrencyData currency; private final CurrencyData currency;
private final BigDecimal nominalAnnualInterestRate; private final BigDecimal nominalAnnualInterestRate;
private final EnumOptionData interestCompoundingPeriodType; private final EnumOptionData interestCompoundingPeriodType;
private final EnumOptionData interestPostingPeriodType;
private final EnumOptionData interestCalculationType; private final EnumOptionData interestCalculationType;
private final EnumOptionData interestCalculationDaysInYearType; private final EnumOptionData interestCalculationDaysInYearType;
private final BigDecimal minRequiredOpeningBalance; private final BigDecimal minRequiredOpeningBalance;
@@ -40,39 +40,49 @@ public class SavingsAccountData {
// associations // associations
private final SavingsAccountSummaryData summary; private final SavingsAccountSummaryData summary;
@SuppressWarnings("unused")
private final Collection<SavingsAccountTransactionData> transactions; private final Collection<SavingsAccountTransactionData> transactions;
// template // template
@SuppressWarnings("unused")
private final Collection<SavingsProductData> productOptions; private final Collection<SavingsProductData> productOptions;
@SuppressWarnings("unused")
private final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions; private final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions;
@SuppressWarnings("unused")
private final Collection<EnumOptionData> interestPostingPeriodTypeOptions;
@SuppressWarnings("unused")
private final Collection<EnumOptionData> interestCalculationTypeOptions; private final Collection<EnumOptionData> interestCalculationTypeOptions;
@SuppressWarnings("unused")
private final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions; private final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions;
@SuppressWarnings("unused")
private final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions; private final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
public static SavingsAccountData instance(final Long id, final String accountNo, final String externalId, 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 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 Long clientId, final String clientName, final Long productId, final String productName, final CurrencyData currency,
final BigDecimal interestRate, final EnumOptionData interestCompoundingPeriodType, final BigDecimal interestRate, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType, final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency, final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
final EnumOptionData lockinPeriodFrequencyType, final SavingsAccountSummaryData summary) { final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType, final SavingsAccountSummaryData summary) {
final Collection<SavingsProductData> productOptions = null; final Collection<SavingsProductData> productOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null; final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null; final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null; final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null; final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<SavingsAccountTransactionData> transactions = null; final Collection<SavingsAccountTransactionData> transactions = null;
return new SavingsAccountData(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName, return new SavingsAccountData(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName,
productId, productName, currency, interestRate, interestCompoundingPeriodType, interestCalculationType, productId, productName, currency, interestRate, interestCompoundingPeriodType, interestPostingPeriodType,
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, summary, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
productOptions, interestCompoundingPeriodTypeOptions, interestCalculationTypeOptions, lockinPeriodFrequencyType, summary, productOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions); interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
} }
public static SavingsAccountData withTemplateOptions(final SavingsAccountData account, public static SavingsAccountData withTemplateOptions(final SavingsAccountData account,
final Collection<SavingsProductData> productOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions, final Collection<SavingsProductData> productOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions, final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions, final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<SavingsAccountTransactionData> transactions) { final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<SavingsAccountTransactionData> transactions) {
@@ -80,10 +90,10 @@ public class SavingsAccountData {
return new SavingsAccountData(account.id, account.accountNo, account.externalId, account.status, account.activationDate, return new SavingsAccountData(account.id, account.accountNo, account.externalId, account.status, account.activationDate,
account.groupId, account.groupName, account.clientId, account.clientName, account.savingsProductId, account.groupId, account.groupName, account.clientId, account.clientName, account.savingsProductId,
account.savingsProductName, account.currency, account.nominalAnnualInterestRate, account.interestCompoundingPeriodType, account.savingsProductName, account.currency, account.nominalAnnualInterestRate, account.interestCompoundingPeriodType,
account.interestCalculationType, account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.interestPostingPeriodType, account.interestCalculationType, account.interestCalculationDaysInYearType,
account.lockinPeriodFrequency, account.lockinPeriodFrequencyType, account.summary, productOptions, account.minRequiredOpeningBalance, account.lockinPeriodFrequency, account.lockinPeriodFrequencyType, account.summary,
interestCompoundingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, productOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
lockinPeriodFrequencyTypeOptions, transactions); interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
} }
public static SavingsAccountData withClientTemplate(final Long clientId, final String clientName, final Long groupId, public static SavingsAccountData withClientTemplate(final Long clientId, final String clientName, final Long groupId,
@@ -99,6 +109,7 @@ public class SavingsAccountData {
final CurrencyData currency = null; final CurrencyData currency = null;
final BigDecimal nominalAnnualInterestRate = null; final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestPeriodType = null; final EnumOptionData interestPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null; final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null; final EnumOptionData interestCalculationDaysInYearType = null;
final BigDecimal minRequiredOpeningBalance = null; final BigDecimal minRequiredOpeningBalance = null;
@@ -106,27 +117,29 @@ public class SavingsAccountData {
final EnumOptionData lockinPeriodFrequencyType = null; final EnumOptionData lockinPeriodFrequencyType = null;
final SavingsAccountSummaryData summary = null; final SavingsAccountSummaryData summary = null;
final Collection<SavingsProductData> productOptions = null; final Collection<SavingsProductData> productOptions = null;
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null; final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null; final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null; final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null; final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<SavingsAccountTransactionData> transactions = null; final Collection<SavingsAccountTransactionData> transactions = null;
return new SavingsAccountData(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName, return new SavingsAccountData(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName,
productId, productName, currency, nominalAnnualInterestRate, interestPeriodType, interestCalculationType, productId, productName, currency, nominalAnnualInterestRate, interestPeriodType, interestPostingPeriodType,
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, summary, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
productOptions, interestCompoundingPeriodTypeOptions, interestCalculationTypeOptions, lockinPeriodFrequencyType, summary, productOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions); interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
} }
private SavingsAccountData(final Long id, final String accountNo, final String externalId, final SavingsAccountStatusEnumData status, 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 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 nominalAnnualInterestRate, final Long productId, final String productName, final CurrencyData currency, final BigDecimal nominalAnnualInterestRate,
final EnumOptionData interestPeriodType, final EnumOptionData interestCalculationType, final EnumOptionData interestPeriodType, final EnumOptionData interestPostingPeriodType,
final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance, final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType, final SavingsAccountSummaryData summary, final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
final EnumOptionData lockinPeriodFrequencyType, final SavingsAccountSummaryData summary,
final Collection<SavingsProductData> productOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions, final Collection<SavingsProductData> productOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions, final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions, final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<SavingsAccountTransactionData> transactions) { final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<SavingsAccountTransactionData> transactions) {
@@ -144,6 +157,7 @@ public class SavingsAccountData {
this.currency = currency; this.currency = currency;
this.nominalAnnualInterestRate = nominalAnnualInterestRate; this.nominalAnnualInterestRate = nominalAnnualInterestRate;
this.interestCompoundingPeriodType = interestPeriodType; this.interestCompoundingPeriodType = interestPeriodType;
this.interestPostingPeriodType = interestPostingPeriodType;
this.interestCalculationType = interestCalculationType; this.interestCalculationType = interestCalculationType;
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType; this.interestCalculationDaysInYearType = interestCalculationDaysInYearType;
this.minRequiredOpeningBalance = minRequiredOpeningBalance; this.minRequiredOpeningBalance = minRequiredOpeningBalance;
@@ -153,6 +167,7 @@ public class SavingsAccountData {
this.productOptions = productOptions; this.productOptions = productOptions;
this.interestCompoundingPeriodTypeOptions = interestCompoundingPeriodTypeOptions; this.interestCompoundingPeriodTypeOptions = interestCompoundingPeriodTypeOptions;
this.interestPostingPeriodTypeOptions = interestPostingPeriodTypeOptions;
this.interestCalculationTypeOptions = interestCalculationTypeOptions; this.interestCalculationTypeOptions = interestCalculationTypeOptions;
this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions; this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions;
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions; this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
@@ -9,6 +9,7 @@ import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.groupI
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationDaysInYearTypeParamName; 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.interestCalculationTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName; import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestPostingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName; 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.lockinPeriodFrequencyTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName; import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
@@ -98,16 +99,33 @@ public class SavingsAccountDataValidator {
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount(); baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
} }
final Integer interestPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCompoundingPeriodTypeParamName, element); if (fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestPeriodType).notNull().inMinMaxRange(1, 7); final Integer interestCompoundingPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCompoundingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
.isOneOfTheseValues(new Object[] { 1, 2, 3, 4, 5, 6, 7, 8 });
}
final Integer interestCalculationType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName, element); if (fromApiJsonHelper.parameterExists(interestPostingPeriodTypeParamName, element)) {
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull().inMinMaxRange(1, 2); final Integer interestPostingPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestPostingPeriodTypeParamName,
element);
baseDataValidator.reset().parameter(interestPostingPeriodTypeParamName).value(interestPostingPeriodType).notNull()
.isOneOfTheseValues(new Object[] { 4, 5, 6, 7 });
}
final Integer interestCalculationDaysInYearType = fromApiJsonHelper.extractIntegerSansLocaleNamed( if (fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) {
interestCalculationDaysInYearTypeParamName, element); final Integer interestCalculationType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName,
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType).notNull() element);
.inOfTheseValues(360, 365); baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull()
.isOneOfTheseValues(new Object[] { 1, 2 });
}
if (fromApiJsonHelper.parameterExists(interestCalculationDaysInYearTypeParamName, element)) {
final Integer interestCalculationDaysInYearType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCalculationDaysInYearTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType)
.notNull().isOneOfTheseValues(360, 365);
}
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) { if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
final BigDecimal minOpeningBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName, final BigDecimal minOpeningBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName,
@@ -213,22 +231,31 @@ public class SavingsAccountDataValidator {
} }
if (this.fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) { if (this.fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
final Integer interestPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCompoundingPeriodTypeParamName, element); final Integer interestCompoundingPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestPeriodType).notNull().inMinMaxRange(1, 7); interestCompoundingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
.isOneOfTheseValues(new Object[] { 1, 2, 3, 4, 5, 6, 7, 8 });
}
if (this.fromApiJsonHelper.parameterExists(interestPostingPeriodTypeParamName, element)) {
final Integer interestPostingPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestPostingPeriodTypeParamName,
element);
baseDataValidator.reset().parameter(interestPostingPeriodTypeParamName).value(interestPostingPeriodType).notNull()
.isOneOfTheseValues(new Object[] { 4, 5, 6, 7 });
} }
if (this.fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) { if (this.fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) {
final Integer interestCalculationType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName, final Integer interestCalculationType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName,
element); element);
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull() baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull()
.inMinMaxRange(1, 2); .isOneOfTheseValues(new Object[] { 1, 2 });
} }
if (this.fromApiJsonHelper.parameterExists(interestCalculationDaysInYearTypeParamName, element)) { if (this.fromApiJsonHelper.parameterExists(interestCalculationDaysInYearTypeParamName, element)) {
final Integer interestCalculationDaysInYearType = fromApiJsonHelper.extractIntegerSansLocaleNamed( final Integer interestCalculationDaysInYearType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCalculationDaysInYearTypeParamName, element); interestCalculationDaysInYearTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType) baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType)
.notNull().inOfTheseValues(360, 365); .notNull().isOneOfTheseValues(360, 365);
} }
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) { if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
@@ -22,6 +22,7 @@ public class SavingsProductData {
private final CurrencyData currency; private final CurrencyData currency;
private final BigDecimal nominalAnnualInterestRate; private final BigDecimal nominalAnnualInterestRate;
private final EnumOptionData interestCompoundingPeriodType; private final EnumOptionData interestCompoundingPeriodType;
private final EnumOptionData interestPostingPeriodType;
private final EnumOptionData interestCalculationType; private final EnumOptionData interestCalculationType;
private final EnumOptionData interestCalculationDaysInYearType; private final EnumOptionData interestCalculationDaysInYearType;
private final BigDecimal minRequiredOpeningBalance; private final BigDecimal minRequiredOpeningBalance;
@@ -34,6 +35,8 @@ public class SavingsProductData {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions; private final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Collection<EnumOptionData> interestPostingPeriodTypeOptions;
@SuppressWarnings("unused")
private final Collection<EnumOptionData> interestCalculationTypeOptions; private final Collection<EnumOptionData> interestCalculationTypeOptions;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions; private final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions;
@@ -41,8 +44,10 @@ public class SavingsProductData {
private final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions; private final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
public static SavingsProductData template(final CurrencyData currency, final EnumOptionData interestCompoundingPeriodType, public static SavingsProductData template(final CurrencyData currency, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType, final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestPeriodTypeOptions, final EnumOptionData interestCalculationDaysInYearType, final Collection<CurrencyData> currencyOptions,
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions, final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions, final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) { final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
@@ -56,9 +61,10 @@ public class SavingsProductData {
final EnumOptionData lockinPeriodFrequencyType = null; final EnumOptionData lockinPeriodFrequencyType = null;
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType, return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequencyType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions, lockinPeriodFrequency, lockinPeriodFrequencyType, currencyOptions, interestCompoundingPeriodTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions); interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions);
} }
/** /**
@@ -66,33 +72,39 @@ public class SavingsProductData {
* {@link SavingsProductData} data with further template data for dropdowns. * {@link SavingsProductData} data with further template data for dropdowns.
*/ */
public static SavingsProductData withTemplate(final SavingsProductData existingProduct, final Collection<CurrencyData> currencyOptions, public static SavingsProductData withTemplate(final SavingsProductData existingProduct, final Collection<CurrencyData> currencyOptions,
final Collection<EnumOptionData> interestPeriodTypeOptions, final Collection<EnumOptionData> interestCalculationTypeOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions, final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) { final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
return new SavingsProductData(existingProduct.id, existingProduct.name, existingProduct.description, existingProduct.currency, return new SavingsProductData(existingProduct.id, existingProduct.name, existingProduct.description, existingProduct.currency,
existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType, existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
existingProduct.interestCalculationType, existingProduct.interestCalculationDaysInYearType, existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
existingProduct.minRequiredOpeningBalance, existingProduct.lockinPeriodFrequency, existingProduct.interestCalculationDaysInYearType, existingProduct.minRequiredOpeningBalance,
existingProduct.lockinPeriodFrequencyType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions, existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions); interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
} }
public static SavingsProductData instance(final Long id, final String name, final String description, final CurrencyData currency, public static SavingsProductData instance(final Long id, final String name, final String description, final CurrencyData currency,
final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType, final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType, final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType) { final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType) {
final Collection<CurrencyData> currencyOptions = null; final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestPeriodTypeOptions = null; final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null; final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null; final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null; final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType, return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequencyType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions, lockinPeriodFrequency, lockinPeriodFrequencyType, currencyOptions, interestCompoundingPeriodTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions); interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions);
} }
public static SavingsProductData lookup(final Long id, final String name) { public static SavingsProductData lookup(final Long id, final String name) {
@@ -101,6 +113,7 @@ public class SavingsProductData {
final String description = null; final String description = null;
final BigDecimal nominalAnnualInterestRate = null; final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestCompoundingPeriodType = null; final EnumOptionData interestCompoundingPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null; final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null; final EnumOptionData interestCalculationDaysInYearType = null;
final BigDecimal minRequiredOpeningBalance = null; final BigDecimal minRequiredOpeningBalance = null;
@@ -108,23 +121,27 @@ public class SavingsProductData {
final EnumOptionData lockinPeriodFrequencyType = null; final EnumOptionData lockinPeriodFrequencyType = null;
final Collection<CurrencyData> currencyOptions = null; final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestPeriodTypeOptions = null; final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null; final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null; final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null; final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType, return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequencyType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions, lockinPeriodFrequency, lockinPeriodFrequencyType, currencyOptions, interestCompoundingPeriodTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions); interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions);
} }
private SavingsProductData(final Long id, final String name, final String description, final CurrencyData currency, private SavingsProductData(final Long id, final String name, final String description, final CurrencyData currency,
final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType, final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType, final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency, final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
final EnumOptionData lockinPeriodFrequencyType, final Collection<CurrencyData> currencyOptions, final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType,
final Collection<EnumOptionData> interestPeriodTypeOptions, final Collection<EnumOptionData> interestCalculationTypeOptions, final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions, final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) { final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
this.id = id; this.id = id;
@@ -133,6 +150,7 @@ public class SavingsProductData {
this.currency = currency; this.currency = currency;
this.nominalAnnualInterestRate = nominalAnnualInterestRate; this.nominalAnnualInterestRate = nominalAnnualInterestRate;
this.interestCompoundingPeriodType = interestCompoundingPeriodType; this.interestCompoundingPeriodType = interestCompoundingPeriodType;
this.interestPostingPeriodType = interestPostingPeriodType;
this.interestCalculationType = interestCalculationType; this.interestCalculationType = interestCalculationType;
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType; this.interestCalculationDaysInYearType = interestCalculationDaysInYearType;
this.minRequiredOpeningBalance = minRequiredOpeningBalance; this.minRequiredOpeningBalance = minRequiredOpeningBalance;
@@ -140,7 +158,8 @@ public class SavingsProductData {
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType; this.lockinPeriodFrequencyType = lockinPeriodFrequencyType;
this.currencyOptions = currencyOptions; this.currencyOptions = currencyOptions;
this.interestCompoundingPeriodTypeOptions = interestPeriodTypeOptions; this.interestCompoundingPeriodTypeOptions = interestCompoundingPeriodTypeOptions;
this.interestPostingPeriodTypeOptions = interestPostingPeriodTypeOptions;
this.interestCalculationTypeOptions = interestCalculationTypeOptions; this.interestCalculationTypeOptions = interestCalculationTypeOptions;
this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions; this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions;
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions; this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
@@ -8,6 +8,7 @@ import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.digits
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationDaysInYearTypeParamName; 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.interestCalculationTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName; import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestPostingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName; 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.lockinPeriodFrequencyTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName; import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
@@ -66,21 +67,27 @@ public class SavingsProductDataValidator {
final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerSansLocaleNamed(digitsAfterDecimalParamName, element); final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerSansLocaleNamed(digitsAfterDecimalParamName, element);
baseDataValidator.reset().parameter(digitsAfterDecimalParamName).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6); baseDataValidator.reset().parameter(digitsAfterDecimalParamName).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName, element); final BigDecimal nominalAnnualInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName, element);
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount(); baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(nominalAnnualInterestRate).notNull().zeroOrPositiveAmount();
final Integer interestCompoundingPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed( final Integer interestCompoundingPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCompoundingPeriodTypeParamName, element); interestCompoundingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull() baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
.inMinMaxRange(1, 8); .isOneOfTheseValues(new Object[] { 1, 2, 3, 4, 5, 6, 7, 8 });
final Integer interestPostingPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestPostingPeriodTypeParamName,
element);
baseDataValidator.reset().parameter(interestPostingPeriodTypeParamName).value(interestPostingPeriodType).notNull()
.isOneOfTheseValues(new Object[] { 4, 5, 6, 7 });
final Integer interestCalculationType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName, element); final Integer interestCalculationType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull().inMinMaxRange(1, 2); baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull()
.isOneOfTheseValues(new Object[] { 1, 2 });
final Integer interestCalculationDaysInYearType = fromApiJsonHelper.extractIntegerSansLocaleNamed( final Integer interestCalculationDaysInYearType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCalculationDaysInYearTypeParamName, element); interestCalculationDaysInYearTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType).notNull() baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType).notNull()
.inOfTheseValues(360, 365); .isOneOfTheseValues(360, 365);
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) { if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
final BigDecimal minOpeningBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName, final BigDecimal minOpeningBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName,
@@ -172,7 +179,7 @@ public class SavingsProductDataValidator {
final Integer interestCalculationDaysInYearType = fromApiJsonHelper.extractIntegerSansLocaleNamed( final Integer interestCalculationDaysInYearType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
interestCalculationDaysInYearTypeParamName, element); interestCalculationDaysInYearTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType) baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType)
.notNull().inOfTheseValues(360, 365); .notNull().isOneOfTheseValues(360, 365);
} }
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) { if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
@@ -94,6 +94,12 @@ public class SavingsAccount extends AbstractPersistable<Long> {
@Column(name = "interest_compounding_period_enum", nullable = false) @Column(name = "interest_compounding_period_enum", nullable = false)
private Integer interestCompoundingPeriodType; private Integer interestCompoundingPeriodType;
/**
* A value from the {@link SavingsInterestPostingPeriodType} enumeration.
*/
@Column(name = "interest_posting_period_enum", nullable = false)
private Integer interestPostingPeriodType;
/** /**
* A value from the {@link SavingsInterestCalculationType} enumeration. * A value from the {@link SavingsInterestCalculationType} enumeration.
*/ */
@@ -107,13 +113,13 @@ public class SavingsAccount extends AbstractPersistable<Long> {
@Column(name = "interest_calculation_days_in_year_type_enum", nullable = false) @Column(name = "interest_calculation_days_in_year_type_enum", nullable = false)
private Integer interestCalculationDaysInYearType; private Integer interestCalculationDaysInYearType;
@Column(name = "min_required_opening_balance", scale = 6, precision = 19, nullable = false) @Column(name = "min_required_opening_balance", scale = 6, precision = 19, nullable = true)
private BigDecimal minRequiredOpeningBalance; private BigDecimal minRequiredOpeningBalance;
@Column(name = "lockin_period_frequency", nullable = false) @Column(name = "lockin_period_frequency", nullable = true)
private Integer lockinPeriodFrequency; private Integer lockinPeriodFrequency;
@Column(name = "lockin_period_frequency_enum", nullable = false) @Column(name = "lockin_period_frequency_enum", nullable = true)
private Integer lockinPeriodFrequencyType; private Integer lockinPeriodFrequencyType;
/** /**
@@ -144,20 +150,22 @@ public class SavingsAccount extends AbstractPersistable<Long> {
public static SavingsAccount createNewAccount(final Client client, final Group group, final SavingsProduct product, public static SavingsAccount createNewAccount(final Client client, final Group group, final SavingsProduct product,
final String accountNo, final String externalId, final BigDecimal interestRate, final String accountNo, final String externalId, final BigDecimal interestRate,
final SavingsCompoundingInterestPeriodType interestPeriodType, final SavingsInterestCalculationType interestCalculationType, final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
final SavingsInterestPostingPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance, final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) { final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) {
final SavingsAccountStatusType status = SavingsAccountStatusType.UNACTIVATED; final SavingsAccountStatusType status = SavingsAccountStatusType.UNACTIVATED;
final LocalDate activationDate = null; final LocalDate activationDate = null;
return new SavingsAccount(client, group, product, accountNo, externalId, status, activationDate, interestRate, interestPeriodType, return new SavingsAccount(client, group, product, accountNo, externalId, status, activationDate, interestRate,
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
lockinPeriodFrequencyType); minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType);
} }
private SavingsAccount(final Client client, final Group group, final SavingsProduct product, final String accountNo, 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 String externalId, final SavingsAccountStatusType status, final LocalDate activationDate, final BigDecimal nominalAnnualInterestRate,
final SavingsCompoundingInterestPeriodType interestPeriodType, final SavingsInterestCalculationType interestCalculationType, final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
final SavingsInterestPostingPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance, final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) { final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) {
this.client = client; this.client = client;
@@ -175,8 +183,9 @@ public class SavingsAccount extends AbstractPersistable<Long> {
if (activationDate != null) { if (activationDate != null) {
this.activationDate = activationDate.toDate(); this.activationDate = activationDate.toDate();
} }
this.nominalAnnualInterestRate = interestRate; this.nominalAnnualInterestRate = nominalAnnualInterestRate;
this.interestCompoundingPeriodType = interestPeriodType.getValue(); this.interestCompoundingPeriodType = interestCompoundingPeriodType.getValue();
this.interestPostingPeriodType = interestPostingPeriodType.getValue();
this.interestCalculationType = interestCalculationType.getValue(); this.interestCalculationType = interestCalculationType.getValue();
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType.getValue(); this.interestCalculationDaysInYearType = interestCalculationDaysInYearType.getValue();
this.minRequiredOpeningBalance = minRequiredOpeningBalance; this.minRequiredOpeningBalance = minRequiredOpeningBalance;
@@ -266,13 +275,47 @@ public class SavingsAccount extends AbstractPersistable<Long> {
return lockedInUntilLocalDate; return lockedInUntilLocalDate;
} }
public void postInterest(final LocalDate interestPostingUpToDate) {
final SavingsInterestPostingPeriodType postingPeriodType = SavingsInterestPostingPeriodType.fromInt(this.interestPostingPeriodType);
List<LocalDate> postingLocalDates = determineInterestPostingDates(getActivationLocalDate(), interestPostingUpToDate,
postingPeriodType);
List<InterestCompoundingPeriodSummary> compoundingPeriods = calculateInterest(interestPostingUpToDate);
//
for (InterestCompoundingPeriodSummary interestCompoundingPeriodSummary : compoundingPeriods) {
}
}
private List<LocalDate> determineInterestPostingDates(final LocalDate activationLocalDate, final LocalDate interestPostingUpToDate,
final SavingsInterestPostingPeriodType postingPeriodType) {
List<LocalDate> postingDates = new ArrayList<LocalDate>();
LocalDate periodStartDate = activationLocalDate;
LocalDate periodEndDate = periodStartDate;
while (!periodStartDate.isAfter(interestPostingUpToDate) && !periodEndDate.isAfter(interestPostingUpToDate)) {
final LocalDate interestPostingLocalDate = determineInterestPostingPeriodEndDateFrom(periodStartDate, postingPeriodType);
postingDates.add(interestPostingLocalDate);
periodEndDate = interestPostingLocalDate;
periodStartDate = interestPostingLocalDate;
}
return postingDates;
}
/** /**
* All interest calculation based on END-OF-DAY-BALANCE. * All interest calculation based on END-OF-DAY-BALANCE.
* *
* Interest calculation is performed on-the-fly over all account * Interest calculation is performed on-the-fly over all account
* transactions. * transactions.
*/ */
public void calculateInterest(final LocalDate interestCalculationEndDate) { public List<InterestCompoundingPeriodSummary> calculateInterest(final LocalDate interestCalculationUpToDate) {
// no openingBalance concept supported yet but probably will to allow // no openingBalance concept supported yet but probably will to allow
// for migrations. // for migrations.
@@ -287,7 +330,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
final SavingsCompoundingInterestPeriodType compoundingPeriodType = SavingsCompoundingInterestPeriodType final SavingsCompoundingInterestPeriodType compoundingPeriodType = SavingsCompoundingInterestPeriodType
.fromInt(this.interestCompoundingPeriodType); .fromInt(this.interestCompoundingPeriodType);
final List<LocalDateInterval> interestCompoundingPeriods = determineInterestCompoundingPeriods(getActivationLocalDate(), final List<LocalDateInterval> interestCompoundingPeriods = determineInterestCompoundingPeriods(getActivationLocalDate(),
interestCalculationEndDate, compoundingPeriodType); interestCalculationUpToDate, compoundingPeriodType);
// determine opening balance, daily interest rate to apply, interest // determine opening balance, daily interest rate to apply, interest
// due, interest to compound for each period // due, interest to compound for each period
@@ -295,6 +338,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
openingAccountBalance, this.nominalAnnualInterestRate, daysInYearType, interestCompoundingPeriods); openingAccountBalance, this.nominalAnnualInterestRate, daysInYearType, interestCompoundingPeriods);
this.summary.updateFromInterestPeriodSummaries(currency, compoundingPeriods); this.summary.updateFromInterestPeriodSummaries(currency, compoundingPeriods);
return compoundingPeriods;
} }
private List<InterestCompoundingPeriodSummary> determineInterestCompoundingPeriodSummaries(final Money openingAccountBalance, private List<InterestCompoundingPeriodSummary> determineInterestCompoundingPeriodSummaries(final Money openingAccountBalance,
@@ -386,6 +431,55 @@ public class SavingsAccount extends AbstractPersistable<Long> {
return interestPeriods; return interestPeriods;
} }
private LocalDate determineInterestPostingPeriodEndDateFrom(final LocalDate periodStartDate,
final SavingsInterestPostingPeriodType interestPostingPeriodType) {
LocalDate periodEndDate = DateUtils.getLocalDateOfTenant();
switch (interestPostingPeriodType) {
case INVALID:
break;
case MONTHLY:
// produce period end date on last day of current month
periodEndDate = periodStartDate.dayOfMonth().withMaximumValue();
break;
case QUATERLY:
// jan 1st to mar 31st, 1st apr to jun 30, jul 1st to sept 30,
// oct 1st to dec 31
int year = periodStartDate.getYearOfEra();
int monthofYear = periodStartDate.getMonthOfYear();
if (monthofYear <= 3) {
periodEndDate = new DateTime().withDate(year, 3, 31).toLocalDate();
} else if (monthofYear <= 6) {
periodEndDate = new DateTime().withDate(year, 6, 30).toLocalDate();
} else if (monthofYear <= 9) {
periodEndDate = new DateTime().withDate(year, 9, 30).toLocalDate();
} else if (monthofYear <= 12) {
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
}
break;
case BI_ANNUAL:
// jan 1st to 30, jul 1st to dec 31
year = periodStartDate.getYearOfEra();
monthofYear = periodStartDate.getMonthOfYear();
if (monthofYear <= 6) {
periodEndDate = new DateTime().withDate(year, 6, 30).toLocalDate();
} else if (monthofYear <= 12) {
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
}
break;
case ANNUAL:
periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
periodEndDate = periodStartDate.dayOfMonth().withMaximumValue();
break;
}
// interest posting always occurs on next day after the period end date.
periodEndDate = periodEndDate.plusDays(1);
return periodEndDate;
}
private LocalDate determineInterestPeriodEndDateFrom(final LocalDate periodStartDate, private LocalDate determineInterestPeriodEndDateFrom(final LocalDate periodStartDate,
final SavingsCompoundingInterestPeriodType interestPeriodType) { final SavingsCompoundingInterestPeriodType interestPeriodType) {
@@ -10,6 +10,7 @@ import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.active
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationDaysInYearTypeParamName; 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.interestCalculationTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName; import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestPostingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName; 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.lockinPeriodFrequencyTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName; import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
@@ -90,22 +91,34 @@ public class SavingsAccountAssembler {
if (command.parameterExists(nominalAnnualInterestRateParamName)) { if (command.parameterExists(nominalAnnualInterestRateParamName)) {
interestRate = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName); interestRate = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName);
} else { } else {
interestRate = product.interestRate(); interestRate = product.nominalAnnualInterestRate();
} }
final boolean active = fromApiJsonHelper.extractBooleanNamed(activeParamName, element); final boolean active = fromApiJsonHelper.extractBooleanNamed(activeParamName, element);
final LocalDate activationDate = fromApiJsonHelper.extractLocalDateNamed(activationDateParamName, element); final LocalDate activationDate = fromApiJsonHelper.extractLocalDateNamed(activationDateParamName, element);
SavingsCompoundingInterestPeriodType interestPeriodType = null; SavingsCompoundingInterestPeriodType interestCompoundingPeriodType = null;
final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName); final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName);
if (interestPeriodTypeValue != null) { if (interestPeriodTypeValue != null) {
interestPeriodType = SavingsCompoundingInterestPeriodType.fromInt(interestPeriodTypeValue); interestCompoundingPeriodType = SavingsCompoundingInterestPeriodType.fromInt(interestPeriodTypeValue);
} else {
interestCompoundingPeriodType = product.interestCompoundingPeriodType();
}
SavingsInterestPostingPeriodType interestPostingPeriodType = null;
final Integer interestPostingPeriodTypeValue = command.integerValueOfParameterNamed(interestPostingPeriodTypeParamName);
if (interestPostingPeriodTypeValue != null) {
interestPostingPeriodType = SavingsInterestPostingPeriodType.fromInt(interestPostingPeriodTypeValue);
} else {
interestPostingPeriodType = product.interestPostingPeriodType();
} }
SavingsInterestCalculationType interestCalculationType = null; SavingsInterestCalculationType interestCalculationType = null;
final Integer interestCalculationTypeValue = command.integerValueOfParameterNamed(interestCalculationTypeParamName); final Integer interestCalculationTypeValue = command.integerValueOfParameterNamed(interestCalculationTypeParamName);
if (interestCalculationTypeValue != null) { if (interestCalculationTypeValue != null) {
interestCalculationType = SavingsInterestCalculationType.fromInt(interestCalculationTypeValue); interestCalculationType = SavingsInterestCalculationType.fromInt(interestCalculationTypeValue);
} else {
interestCalculationType = product.interestCalculationType();
} }
SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType = null; SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType = null;
@@ -113,6 +126,8 @@ public class SavingsAccountAssembler {
.integerValueOfParameterNamed(interestCalculationDaysInYearTypeParamName); .integerValueOfParameterNamed(interestCalculationDaysInYearTypeParamName);
if (interestCalculationDaysInYearTypeValue != null) { if (interestCalculationDaysInYearTypeValue != null) {
interestCalculationDaysInYearType = SavingsInterestCalculationDaysInYearType.fromInt(interestCalculationDaysInYearTypeValue); interestCalculationDaysInYearType = SavingsInterestCalculationDaysInYearType.fromInt(interestCalculationDaysInYearTypeValue);
} else {
interestCalculationDaysInYearType = product.interestCalculationDaysInYearType();
} }
BigDecimal minRequiredOpeningBalance = null; BigDecimal minRequiredOpeningBalance = null;
@@ -141,8 +156,8 @@ public class SavingsAccountAssembler {
} }
final SavingsAccount account = SavingsAccount.createNewAccount(client, group, product, accountNo, externalId, interestRate, final SavingsAccount account = SavingsAccount.createNewAccount(client, group, product, accountNo, externalId, interestRate,
interestPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
lockinPeriodFrequency, lockinPeriodFrequencyType); minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType);
account.setHelpers(this.savingsAccountTransactionSummaryWrapper); account.setHelpers(this.savingsAccountTransactionSummaryWrapper);
if (active) { if (active) {
@@ -0,0 +1,56 @@
/**
* 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;
/**
* The interest posting period is the span of time at the end of which savings
* earned but not yet credited/posted in a client’s account is credited/posted.
*/
public enum SavingsInterestPostingPeriodType {
INVALID(0, "savingsInterestPostingPeriodType.invalid"), //
MONTHLY(4, "savingsInterestPostingPeriodType.monthly"), //
QUATERLY(5, "savingsInterestPostingPeriodType.quarterly"), //
BI_ANNUAL(6, "savingsInterestPostingPeriodType.biannual"), //
ANNUAL(7, "savingsInterestPostingPeriodType.annual");
private final Integer value;
private final String code;
private SavingsInterestPostingPeriodType(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 SavingsInterestPostingPeriodType fromInt(final Integer type) {
SavingsInterestPostingPeriodType repaymentFrequencyType = SavingsInterestPostingPeriodType.INVALID;
if (type != null) {
switch (type) {
case 4:
repaymentFrequencyType = SavingsInterestPostingPeriodType.MONTHLY;
break;
case 5:
repaymentFrequencyType = SavingsInterestPostingPeriodType.QUATERLY;
break;
case 6:
repaymentFrequencyType = SavingsInterestPostingPeriodType.BI_ANNUAL;
break;
case 7:
repaymentFrequencyType = SavingsInterestPostingPeriodType.ANNUAL;
break;
}
}
return repaymentFrequencyType;
}
}
@@ -11,6 +11,7 @@ import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.digits
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationDaysInYearTypeParamName; 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.interestCalculationTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName; import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestPostingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.localeParamName; 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.lockinPeriodFrequencyParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyTypeParamName; import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
@@ -53,11 +54,18 @@ public class SavingsProduct extends AbstractPersistable<Long> {
* The interest period is the span of time at the end of which savings in a * The interest period is the span of time at the end of which savings in a
* client’s account earn interest. * client’s account earn interest.
* *
* A value from the {@link SavingsCompoundingInterestPeriodType} enumeration. * A value from the {@link SavingsCompoundingInterestPeriodType}
* enumeration.
*/ */
@Column(name = "interest_compounding_period_enum", nullable = false) @Column(name = "interest_compounding_period_enum", nullable = false)
private Integer interestCompoundingPeriodType; private Integer interestCompoundingPeriodType;
/**
* A value from the {@link SavingsInterestPostingPeriodType} enumeration.
*/
@Column(name = "interest_posting_period_enum", nullable = false)
private Integer interestPostingPeriodType;
/** /**
* A value from the {@link SavingsInterestCalculationType} enumeration. * A value from the {@link SavingsInterestCalculationType} enumeration.
*/ */
@@ -71,23 +79,24 @@ public class SavingsProduct extends AbstractPersistable<Long> {
@Column(name = "interest_calculation_days_in_year_type_enum", nullable = false) @Column(name = "interest_calculation_days_in_year_type_enum", nullable = false)
private Integer interestCalculationDaysInYearType; private Integer interestCalculationDaysInYearType;
@Column(name = "min_required_opening_balance", scale = 6, precision = 19, nullable = false) @Column(name = "min_required_opening_balance", scale = 6, precision = 19, nullable = true)
private BigDecimal minRequiredOpeningBalance; private BigDecimal minRequiredOpeningBalance;
@Column(name = "lockin_period_frequency", nullable = false) @Column(name = "lockin_period_frequency", nullable = true)
private Integer lockinPeriodFrequency; private Integer lockinPeriodFrequency;
@Column(name = "lockin_period_frequency_enum", nullable = false) @Column(name = "lockin_period_frequency_enum", nullable = true)
private Integer lockinPeriodFrequencyType; private Integer lockinPeriodFrequencyType;
public static SavingsProduct createNew(final String name, final String description, final MonetaryCurrency currency, public static SavingsProduct createNew(final String name, final String description, final MonetaryCurrency currency,
final BigDecimal interestRate, final SavingsCompoundingInterestPeriodType interestPeriodType, final BigDecimal interestRate, final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
final SavingsInterestCalculationType interestCalculationType, final SavingsInterestPostingPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance, final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) { final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) {
return new SavingsProduct(name, description, currency, interestRate, interestPeriodType, interestCalculationType, return new SavingsProduct(name, description, currency, interestRate, interestCompoundingPeriodType, interestPostingPeriodType,
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType); interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
lockinPeriodFrequencyType);
} }
protected SavingsProduct() { protected SavingsProduct() {
@@ -96,7 +105,8 @@ public class SavingsProduct extends AbstractPersistable<Long> {
} }
private SavingsProduct(final String name, final String description, final MonetaryCurrency currency, final BigDecimal interestRate, private SavingsProduct(final String name, final String description, final MonetaryCurrency currency, final BigDecimal interestRate,
final SavingsCompoundingInterestPeriodType interestPeriodType, final SavingsInterestCalculationType interestCalculationType, final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
final SavingsInterestPostingPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance, final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) { final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) {
@@ -105,7 +115,8 @@ public class SavingsProduct extends AbstractPersistable<Long> {
this.currency = currency; this.currency = currency;
this.nominalAnnualInterestRate = interestRate; this.nominalAnnualInterestRate = interestRate;
this.interestCompoundingPeriodType = interestPeriodType.getValue(); this.interestCompoundingPeriodType = interestCompoundingPeriodType.getValue();
this.interestPostingPeriodType = interestPostingPeriodType.getValue();
this.interestCalculationType = interestCalculationType.getValue(); this.interestCalculationType = interestCalculationType.getValue();
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType.getValue(); this.interestCalculationDaysInYearType = interestCalculationDaysInYearType.getValue();
@@ -125,10 +136,26 @@ public class SavingsProduct extends AbstractPersistable<Long> {
return this.currency.copy(); return this.currency.copy();
} }
public BigDecimal interestRate() { public BigDecimal nominalAnnualInterestRate() {
return Money.of(this.currency, this.nominalAnnualInterestRate).getAmount(); return Money.of(this.currency, this.nominalAnnualInterestRate).getAmount();
} }
public SavingsCompoundingInterestPeriodType interestCompoundingPeriodType() {
return SavingsCompoundingInterestPeriodType.fromInt(this.interestCompoundingPeriodType);
}
public SavingsInterestPostingPeriodType interestPostingPeriodType() {
return SavingsInterestPostingPeriodType.fromInt(this.interestPostingPeriodType);
}
public SavingsInterestCalculationType interestCalculationType() {
return SavingsInterestCalculationType.fromInt(this.interestCalculationType);
}
public SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType() {
return SavingsInterestCalculationDaysInYearType.fromInt(this.interestCalculationDaysInYearType);
}
public BigDecimal minRequiredOpeningBalance() { public BigDecimal minRequiredOpeningBalance() {
return this.minRequiredOpeningBalance; return this.minRequiredOpeningBalance;
} }
@@ -193,6 +220,12 @@ public class SavingsProduct extends AbstractPersistable<Long> {
this.interestCompoundingPeriodType = SavingsCompoundingInterestPeriodType.fromInt(newValue).getValue(); this.interestCompoundingPeriodType = SavingsCompoundingInterestPeriodType.fromInt(newValue).getValue();
} }
if (command.isChangeInIntegerParameterNamed(interestPostingPeriodTypeParamName, this.interestPostingPeriodType)) {
final Integer newValue = command.integerValueOfParameterNamed(interestPostingPeriodTypeParamName);
actualChanges.put(interestPostingPeriodTypeParamName, newValue);
this.interestPostingPeriodType = SavingsInterestPostingPeriodType.fromInt(newValue).getValue();
}
if (command.isChangeInIntegerParameterNamed(interestCalculationTypeParamName, this.interestCalculationType)) { if (command.isChangeInIntegerParameterNamed(interestCalculationTypeParamName, this.interestCalculationType)) {
final Integer newValue = command.integerValueOfParameterNamed(interestCalculationTypeParamName); final Integer newValue = command.integerValueOfParameterNamed(interestCalculationTypeParamName);
actualChanges.put(interestCalculationTypeParamName, newValue); actualChanges.put(interestCalculationTypeParamName, newValue);
@@ -6,6 +6,7 @@ import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.digits
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCalculationDaysInYearTypeParamName; 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.interestCalculationTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName; import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestPostingPeriodTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName; 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.lockinPeriodFrequencyTypeParamName;
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName; import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
@@ -32,10 +33,16 @@ public class SavingsProductAssembler {
final BigDecimal interestRate = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName); final BigDecimal interestRate = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName);
SavingsCompoundingInterestPeriodType interestPeriodType = null; SavingsCompoundingInterestPeriodType interestCompoundingPeriodType = null;
final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName); final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName);
if (interestPeriodTypeValue != null) { if (interestPeriodTypeValue != null) {
interestPeriodType = SavingsCompoundingInterestPeriodType.fromInt(interestPeriodTypeValue); interestCompoundingPeriodType = SavingsCompoundingInterestPeriodType.fromInt(interestPeriodTypeValue);
}
SavingsInterestPostingPeriodType interestPostingPeriodType = null;
final Integer interestPostingPeriodTypeValue = command.integerValueOfParameterNamed(interestPostingPeriodTypeParamName);
if (interestPostingPeriodTypeValue != null) {
interestPostingPeriodType = SavingsInterestPostingPeriodType.fromInt(interestPostingPeriodTypeValue);
} }
SavingsInterestCalculationType interestCalculationType = null; SavingsInterestCalculationType interestCalculationType = null;
@@ -60,7 +67,8 @@ public class SavingsProductAssembler {
lockinPeriodFrequencyType = SavingsPeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue); lockinPeriodFrequencyType = SavingsPeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
} }
return SavingsProduct.createNew(name, description, currency, interestRate, interestPeriodType, interestCalculationType, return SavingsProduct.createNew(name, description, currency, interestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType,
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType); interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType);
} }
} }
@@ -0,0 +1,26 @@
package org.mifosplatform.portfolio.savings.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.savings.service.SavingsAccountWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class PostInterestSavingsAccountCommandHandler implements NewCommandSourceHandler {
private final SavingsAccountWritePlatformService savingAccountWritePlatformService;
@Autowired
public PostInterestSavingsAccountCommandHandler(final SavingsAccountWritePlatformService savingAccountWritePlatformService) {
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.savingAccountWritePlatformService.postInterest(command.getSavingsId(), command);
}
}
@@ -30,6 +30,7 @@ import org.mifosplatform.portfolio.savings.data.SavingsProductData;
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType; import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType; import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType; import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPostingPeriodType;
import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType; import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType;
import org.mifosplatform.portfolio.savings.exception.SavingsAccountNotFoundException; import org.mifosplatform.portfolio.savings.exception.SavingsAccountNotFoundException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -105,6 +106,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, "); sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
sqlBuilder.append("sa.nominal_annual_interest_rate as nominalAnnualInterestRate, "); sqlBuilder.append("sa.nominal_annual_interest_rate as nominalAnnualInterestRate, ");
sqlBuilder.append("sa.interest_compounding_period_enum as interestCompoundingPeriodType, "); sqlBuilder.append("sa.interest_compounding_period_enum as interestCompoundingPeriodType, ");
sqlBuilder.append("sa.interest_posting_period_enum as interestPostingPeriodType, ");
sqlBuilder.append("sa.interest_calculation_type_enum as interestCalculationType, "); sqlBuilder.append("sa.interest_calculation_type_enum as interestCalculationType, ");
sqlBuilder.append("sa.interest_calculation_days_in_year_type_enum as interestCalculationDaysInYearType, "); sqlBuilder.append("sa.interest_calculation_days_in_year_type_enum as interestCalculationDaysInYearType, ");
sqlBuilder.append("sa.min_required_opening_balance as minRequiredOpeningBalance, "); sqlBuilder.append("sa.min_required_opening_balance as minRequiredOpeningBalance, ");
@@ -162,6 +164,9 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.fromInt(JdbcSupport.getInteger(rs, .compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.fromInt(JdbcSupport.getInteger(rs,
"interestCompoundingPeriodType"))); "interestCompoundingPeriodType")));
final EnumOptionData interestPostingPeriodType = SavingsEnumerations.interestPostingPeriodType(SavingsInterestPostingPeriodType
.fromInt(JdbcSupport.getInteger(rs, "interestPostingPeriodType")));
final EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(SavingsInterestCalculationType final EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(SavingsInterestCalculationType
.fromInt(JdbcSupport.getInteger(rs, "interestCalculationType"))); .fromInt(JdbcSupport.getInteger(rs, "interestCalculationType")));
@@ -188,11 +193,10 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
final SavingsAccountSummaryData summary = new SavingsAccountSummaryData(currency, totalDeposits, totalWithdrawals, final SavingsAccountSummaryData summary = new SavingsAccountSummaryData(currency, totalDeposits, totalWithdrawals,
totalInterestEarned, totalInterestPosted, accountBalance); totalInterestEarned, totalInterestPosted, accountBalance);
return SavingsAccountData return SavingsAccountData.instance(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName,
.instance(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName, productId, productId, productName, currency, nominalAnnualInterestRate, interestCompoundingPeriodType, interestPostingPeriodType,
productName, currency, nominalAnnualInterestRate, interestCompoundingPeriodType, interestCalculationType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, lockinPeriodFrequencyType, summary);
summary);
} }
} }
@@ -223,6 +227,9 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService
.retrieveCompoundingInterestPeriodTypeOptions(); .retrieveCompoundingInterestPeriodTypeOptions();
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = this.dropdownReadPlatformService
.retrieveInterestPostingPeriodTypeOptions();
final Collection<EnumOptionData> interestCalculationTypeOptions = this.dropdownReadPlatformService final Collection<EnumOptionData> interestCalculationTypeOptions = this.dropdownReadPlatformService
.retrieveInterestCalculationTypeOptions(); .retrieveInterestCalculationTypeOptions();
@@ -234,8 +241,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
final Collection<SavingsAccountTransactionData> transactions = null; final Collection<SavingsAccountTransactionData> transactions = null;
template = SavingsAccountData.withTemplateOptions(template, productOptions, interestCompoundingPeriodTypeOptions, template = SavingsAccountData.withTemplateOptions(template, productOptions, interestCompoundingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
transactions); lockinPeriodFrequencyTypeOptions, transactions);
} else { } else {
String clientName = null; String clientName = null;
@@ -251,14 +258,15 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
template = SavingsAccountData.withClientTemplate(clientId, clientName, groupId, groupName); template = SavingsAccountData.withClientTemplate(clientId, clientName, groupId, groupName);
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null; final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null; final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null; final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null; final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<SavingsAccountTransactionData> transactions = null; final Collection<SavingsAccountTransactionData> transactions = null;
template = SavingsAccountData.withTemplateOptions(template, productOptions, interestCompoundingPeriodTypeOptions, template = SavingsAccountData.withTemplateOptions(template, productOptions, interestCompoundingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
transactions); lockinPeriodFrequencyTypeOptions, transactions);
} }
return template; return template;
@@ -391,6 +399,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, "); sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
sqlBuilder.append("sp.nominal_annual_interest_rate as nominalAnnualIterestRate, "); sqlBuilder.append("sp.nominal_annual_interest_rate as nominalAnnualIterestRate, ");
sqlBuilder.append("sp.interest_compounding_period_enum as interestCompoundingPeriodType, "); sqlBuilder.append("sp.interest_compounding_period_enum as interestCompoundingPeriodType, ");
sqlBuilder.append("sp.interest_posting_period_enum as interestPostingPeriodType, ");
sqlBuilder.append("sp.interest_calculation_type_enum as interestCalculationType, "); sqlBuilder.append("sp.interest_calculation_type_enum as interestCalculationType, ");
sqlBuilder.append("sp.interest_calculation_days_in_year_type_enum as interestCalculationDaysInYearType, "); sqlBuilder.append("sp.interest_calculation_days_in_year_type_enum as interestCalculationDaysInYearType, ");
sqlBuilder.append("sp.min_required_opening_balance as minRequiredOpeningBalance, "); sqlBuilder.append("sp.min_required_opening_balance as minRequiredOpeningBalance, ");
@@ -422,9 +431,12 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
final BigDecimal nominalAnnualIterestRate = rs.getBigDecimal("nominalAnnualIterestRate"); final BigDecimal nominalAnnualIterestRate = rs.getBigDecimal("nominalAnnualIterestRate");
EnumOptionData interestPeriodType = SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType EnumOptionData interestCompoundingPeriodType = SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType
.fromInt(JdbcSupport.getInteger(rs, "interestCompoundingPeriodType"))); .fromInt(JdbcSupport.getInteger(rs, "interestCompoundingPeriodType")));
final EnumOptionData interestPostingPeriodType = SavingsEnumerations.interestPostingPeriodType(SavingsInterestPostingPeriodType
.fromInt(JdbcSupport.getInteger(rs, "interestPostingPeriodType")));
EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(SavingsInterestCalculationType EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(SavingsInterestCalculationType
.fromInt(JdbcSupport.getInteger(rs, "interestCalculationType"))); .fromInt(JdbcSupport.getInteger(rs, "interestCalculationType")));
@@ -459,11 +471,10 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
final SavingsAccountStatusEnumData status = null; final SavingsAccountStatusEnumData status = null;
final LocalDate activationDate = null; final LocalDate activationDate = null;
final SavingsAccountSummaryData summary = null; final SavingsAccountSummaryData summary = null;
return SavingsAccountData return SavingsAccountData.instance(null, null, null, status, activationDate, groupId, groupName, clientId, clientName,
.instance(null, null, null, status, activationDate, groupId, groupName, clientId, clientName, productId, productName, productId, productName, currency, nominalAnnualIterestRate, interestCompoundingPeriodType, interestPostingPeriodType,
currency, nominalAnnualIterestRate, interestPeriodType, interestCalculationType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, lockinPeriodFrequencyType, summary);
summary);
} }
} }
} }
@@ -23,4 +23,6 @@ public interface SavingsAccountWritePlatformService {
CommandProcessingResult withdrawal(Long savingsId, JsonCommand command); CommandProcessingResult withdrawal(Long savingsId, JsonCommand command);
CommandProcessingResult calculateInterest(Long savingsId, JsonCommand command); CommandProcessingResult calculateInterest(Long savingsId, JsonCommand command);
CommandProcessingResult postInterest(Long savingsId, JsonCommand command);
} }
@@ -334,4 +334,23 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
.withSavingsId(savingsId) // .withSavingsId(savingsId) //
.build(); .build();
} }
@Override
public CommandProcessingResult postInterest(final Long savingsId, final JsonCommand command) {
this.context.authenticatedUser();
final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(savingsId);
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(today);
this.savingAccountRepository.save(account);
return new CommandProcessingResultBuilder() //
.withEntityId(savingsId) //
.withOfficeId(account.officeId()) //
.withClientId(account.clientId()) //
.withGroupId(account.groupId()) //
.withSavingsId(savingsId) //
.build();
}
} }
@@ -10,6 +10,8 @@ public interface SavingsDropdownReadPlatformService {
Collection<EnumOptionData> retrieveCompoundingInterestPeriodTypeOptions(); Collection<EnumOptionData> retrieveCompoundingInterestPeriodTypeOptions();
Collection<EnumOptionData> retrieveInterestPostingPeriodTypeOptions();
Collection<EnumOptionData> retrieveInterestCalculationTypeOptions(); Collection<EnumOptionData> retrieveInterestCalculationTypeOptions();
Collection<EnumOptionData> retrieveInterestCalculationDaysInYearTypeOptions(); Collection<EnumOptionData> retrieveInterestCalculationDaysInYearTypeOptions();
@@ -8,6 +8,7 @@ import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType; import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType; import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType; import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPostingPeriodType;
import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType; import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -42,6 +43,18 @@ public class SavingsDropdownReadPlatformServiceImpl implements SavingsDropdownRe
return allowedOptions; return allowedOptions;
} }
@Override
public Collection<EnumOptionData> retrieveInterestPostingPeriodTypeOptions() {
List<EnumOptionData> allowedOptions = Arrays.asList( //
SavingsEnumerations.interestPostingPeriodType(SavingsInterestPostingPeriodType.MONTHLY), //
SavingsEnumerations.interestPostingPeriodType(SavingsInterestPostingPeriodType.QUATERLY), //
SavingsEnumerations.interestPostingPeriodType(SavingsInterestPostingPeriodType.BI_ANNUAL), //
SavingsEnumerations.interestPostingPeriodType(SavingsInterestPostingPeriodType.ANNUAL) //
);
return allowedOptions;
}
@Override @Override
public Collection<EnumOptionData> retrieveInterestCalculationTypeOptions() { public Collection<EnumOptionData> retrieveInterestCalculationTypeOptions() {
List<EnumOptionData> allowedOptions = Arrays.asList( // List<EnumOptionData> allowedOptions = Arrays.asList( //
@@ -13,6 +13,7 @@ import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransactionType;
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType; import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType; import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType; import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPostingPeriodType;
import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType; import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType;
public class SavingsEnumerations { public class SavingsEnumerations {
@@ -109,6 +110,40 @@ public class SavingsEnumerations {
return optionData; return optionData;
} }
public static EnumOptionData interestPostingPeriodType(final Integer type) {
return interestPostingPeriodType(SavingsInterestPostingPeriodType.fromInt(type));
}
public static EnumOptionData interestPostingPeriodType(final SavingsInterestPostingPeriodType type) {
final String codePrefix = "savings.interest.posting.period.";
EnumOptionData optionData = new EnumOptionData(SavingsInterestPostingPeriodType.INVALID.getValue().longValue(),
SavingsInterestPostingPeriodType.INVALID.getCode(), "Invalid");
switch (type) {
case INVALID:
break;
case MONTHLY:
optionData = new EnumOptionData(SavingsInterestPostingPeriodType.MONTHLY.getValue().longValue(), codePrefix
+ SavingsInterestPostingPeriodType.MONTHLY.getCode(), "Monthly");
break;
case QUATERLY:
optionData = new EnumOptionData(SavingsInterestPostingPeriodType.QUATERLY.getValue().longValue(), codePrefix
+ SavingsInterestPostingPeriodType.QUATERLY.getCode(), "Quarterly");
break;
case BI_ANNUAL:
optionData = new EnumOptionData(SavingsInterestPostingPeriodType.BI_ANNUAL.getValue().longValue(), codePrefix
+ SavingsInterestPostingPeriodType.BI_ANNUAL.getCode(), "Semi-Annual");
break;
case ANNUAL:
optionData = new EnumOptionData(SavingsInterestPostingPeriodType.ANNUAL.getValue().longValue(), codePrefix
+ SavingsInterestPostingPeriodType.ANNUAL.getCode(), "Annually");
break;
}
return optionData;
}
public static EnumOptionData interestPeriodType(final Integer type) { public static EnumOptionData interestPeriodType(final Integer type) {
return compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.fromInt(type)); return compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.fromInt(type));
} }
@@ -19,6 +19,7 @@ import org.mifosplatform.portfolio.savings.data.SavingsProductData;
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType; import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType; import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType; import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPostingPeriodType;
import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType; import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType;
import org.mifosplatform.portfolio.savings.exception.SavingsProductNotFoundException; import org.mifosplatform.portfolio.savings.exception.SavingsProductNotFoundException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -82,6 +83,7 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, "); sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
sqlBuilder.append("sp.nominal_annual_interest_rate as nominalAnnualInterestRate, "); sqlBuilder.append("sp.nominal_annual_interest_rate as nominalAnnualInterestRate, ");
sqlBuilder.append("sp.interest_compounding_period_enum as compoundingInterestPeriodType, "); sqlBuilder.append("sp.interest_compounding_period_enum as compoundingInterestPeriodType, ");
sqlBuilder.append("sp.interest_posting_period_enum as interestPostingPeriodType, ");
sqlBuilder.append("sp.interest_calculation_type_enum as interestCalculationType, "); sqlBuilder.append("sp.interest_calculation_type_enum as interestCalculationType, ");
sqlBuilder.append("sp.interest_calculation_days_in_year_type_enum as interestCalculationDaysInYearType, "); sqlBuilder.append("sp.interest_calculation_days_in_year_type_enum as interestCalculationDaysInYearType, ");
sqlBuilder.append("sp.min_required_opening_balance as minRequiredOpeningBalance, "); sqlBuilder.append("sp.min_required_opening_balance as minRequiredOpeningBalance, ");
@@ -118,6 +120,10 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.fromInt(JdbcSupport.getInteger(rs, .compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.fromInt(JdbcSupport.getInteger(rs,
"compoundingInterestPeriodType"))); "compoundingInterestPeriodType")));
SavingsInterestPostingPeriodType interestPostingPeriod = SavingsInterestPostingPeriodType.fromInt(JdbcSupport.getInteger(rs,
"interestPostingPeriodType"));
EnumOptionData interestPostingPeriodType = SavingsEnumerations.interestPostingPeriodType(interestPostingPeriod);
EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(SavingsInterestCalculationType EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(SavingsInterestCalculationType
.fromInt(JdbcSupport.getInteger(rs, "interestCalculationType"))); .fromInt(JdbcSupport.getInteger(rs, "interestCalculationType")));
@@ -140,8 +146,8 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
} }
return SavingsProductData.instance(id, name, description, currency, nominalAnnualInterestRate, compoundingInterestPeriodType, return SavingsProductData.instance(id, name, description, currency, nominalAnnualInterestRate, compoundingInterestPeriodType,
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequencyType); lockinPeriodFrequency, lockinPeriodFrequencyType);
} }
} }