MIFOSX-250: wip on interest compounding and posting
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
public boolean isSavingsAccountInterestPosting() {
|
||||
return this.actionName.equalsIgnoreCase("POSTINTEREST") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isCalendarResource() {
|
||||
return this.entityName.equalsIgnoreCase("CALENDAR");
|
||||
}
|
||||
|
||||
+10
-1
@@ -717,11 +717,20 @@ public class CommandWrapperBuilder {
|
||||
this.actionName = "CALCULATEINTEREST";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.savingsId = accountId;
|
||||
this.entityId = null;
|
||||
this.entityId = accountId;
|
||||
this.href = "/savingsaccounts/" + accountId + "?command=calculateInterest";
|
||||
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) {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "CALENDAR";
|
||||
|
||||
+2
@@ -370,6 +370,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
handler = applicationContext.getBean("activateSavingsAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isSavingsAccountInterestCalculation()) {
|
||||
handler = applicationContext.getBean("calculateInterestSavingsAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isSavingsAccountInterestPosting()) {
|
||||
handler = applicationContext.getBean("postInterestSavingsAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
|
||||
+1
-1
@@ -192,7 +192,7 @@ public class DataValidatorBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataValidatorBuilder inOfTheseValues(final Object... values) {
|
||||
public DataValidatorBuilder isOneOfTheseValues(final Object... values) {
|
||||
if (value == null && ignoreNullValue) { return this; }
|
||||
|
||||
if (value != null) {
|
||||
|
||||
+7
-1
@@ -9,10 +9,12 @@ public class UnrecognizedQueryParamException extends RuntimeException {
|
||||
|
||||
private final String queryParamKey;
|
||||
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.queryParamValue = queryParamValue;
|
||||
this.supportedParams = supportedParams;
|
||||
}
|
||||
|
||||
public String getQueryParamKey() {
|
||||
@@ -22,4 +24,8 @@ public class UnrecognizedQueryParamException extends RuntimeException {
|
||||
public String getQueryParamValue() {
|
||||
return queryParamValue;
|
||||
}
|
||||
|
||||
public Object[] getSupportedParams() {
|
||||
return this.supportedParams;
|
||||
}
|
||||
}
|
||||
+14
-11
@@ -33,22 +33,25 @@ import org.springframework.stereotype.Component;
|
||||
public class UnrecognizedQueryParamExceptionMapper implements ExceptionMapper<UnrecognizedQueryParamException> {
|
||||
|
||||
@Override
|
||||
public Response toResponse(UnrecognizedQueryParamException exception) {
|
||||
public Response toResponse(final UnrecognizedQueryParamException exception) {
|
||||
|
||||
String parameterName = exception.getQueryParamKey();
|
||||
String parameterValue = exception.getQueryParamValue();
|
||||
final String parameterName = exception.getQueryParamKey();
|
||||
final String parameterValue = exception.getQueryParamValue();
|
||||
|
||||
StringBuilder validationErrorCode = new StringBuilder("error.msg.query.parameter.value.unsupported");
|
||||
StringBuilder defaultEnglishMessage = new StringBuilder("The query parameter ").append(parameterName)
|
||||
.append(" has an unsupported value of: ").append(parameterValue);
|
||||
ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(),
|
||||
parameterName, parameterName, parameterValue);
|
||||
final StringBuilder validationErrorCode = new StringBuilder("error.msg.query.parameter.value.unsupported");
|
||||
final StringBuilder defaultEnglishMessage = new StringBuilder("The query parameter ") //
|
||||
.append(parameterName) //
|
||||
.append(" has an unsupported value of: ") //
|
||||
.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);
|
||||
|
||||
ApiGlobalErrorResponse invalidParameterError = ApiGlobalErrorResponse.badClientRequest("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", errors);
|
||||
final ApiGlobalErrorResponse invalidParameterError = ApiGlobalErrorResponse.badClientRequest(
|
||||
"validation.msg.validation.errors.exist", "Validation errors exist.", errors);
|
||||
|
||||
return Response.status(Status.BAD_REQUEST).entity(invalidParameterError).type(MediaType.APPLICATION_JSON).build();
|
||||
}
|
||||
|
||||
+10
-3
@@ -141,6 +141,7 @@ public class SavingsAccountsApiResource {
|
||||
Collection<SavingsAccountTransactionData> transactions = null;
|
||||
Collection<SavingsProductData> productOptions = null;
|
||||
Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
||||
Collection<EnumOptionData> interestCompoundingPostingTypeOptions = null;
|
||||
Collection<EnumOptionData> interestCalculationTypeOptions = null;
|
||||
Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||
Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
@@ -166,12 +167,14 @@ public class SavingsAccountsApiResource {
|
||||
if (settings.isTemplate()) {
|
||||
productOptions = this.savingsProductReadPlatformService.retrieveAllForLookup();
|
||||
interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService.retrieveCompoundingInterestPeriodTypeOptions();
|
||||
interestCompoundingPostingTypeOptions = this.dropdownReadPlatformService.retrieveInterestPostingPeriodTypeOptions();
|
||||
interestCalculationTypeOptions = this.dropdownReadPlatformService.retrieveInterestCalculationTypeOptions();
|
||||
lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveLockinPeriodFrequencyTypeOptions();
|
||||
}
|
||||
|
||||
return SavingsAccountData.withTemplateOptions(savingsAccount, productOptions, interestCompoundingPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
|
||||
interestCompoundingPostingTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@@ -204,11 +207,15 @@ public class SavingsAccountsApiResource {
|
||||
} else if (is(commandParam, "calculateInterest")) {
|
||||
final CommandWrapper commandRequest = builder.savingsAccountInterestCalculation(accountId).build();
|
||||
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) {
|
||||
// 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);
|
||||
|
||||
+15
-12
@@ -32,8 +32,8 @@ public class SavingsApiConstants {
|
||||
public static final String currencyCodeParamName = "currencyCode";
|
||||
public static final String digitsAfterDecimalParamName = "digitsAfterDecimal";
|
||||
public static final String nominalAnnualInterestRateParamName = "nominalAnnualInterestRate";
|
||||
|
||||
public static final String interestCompoundingPeriodTypeParamName = "interestCompoundingPeriodType";
|
||||
public static final String interestPostingPeriodTypeParamName = "interestPostingPeriodType";
|
||||
public static final String interestCalculationTypeParamName = "interestCalculationType";
|
||||
public static final String interestCalculationDaysInYearTypeParamName = "interestCalculationDaysInYearType";
|
||||
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,
|
||||
nameParamName, descriptionParamName, currencyCodeParamName, digitsAfterDecimalParamName, nominalAnnualInterestRateParamName,
|
||||
interestCompoundingPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName,
|
||||
minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName));
|
||||
interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName, interestCalculationTypeParamName,
|
||||
interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName,
|
||||
lockinPeriodFrequencyTypeParamName));
|
||||
|
||||
/**
|
||||
* 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,
|
||||
nameParamName, descriptionParamName, "currency", digitsAfterDecimalParamName, nominalAnnualInterestRateParamName,
|
||||
interestCompoundingPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName,
|
||||
minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName, "currencyOptions",
|
||||
"interestRatePeriodFrequencyTypeOptions", "lockinPeriodFrequencyTypeOptions"));
|
||||
interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName, interestCalculationTypeParamName,
|
||||
interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName,
|
||||
lockinPeriodFrequencyTypeParamName, "currencyOptions", "interestCompoundingPeriodTypeOptions",
|
||||
"interestPostingPeriodTypeOptions", "interestCalculationTypeOptions", "interestCalculationDaysInYearTypeOptions",
|
||||
"lockinPeriodFrequencyTypeOptions"));
|
||||
|
||||
public static final Set<String> SAVINGS_ACCOUNT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
dateFormatParamName, accountNoParamName, externalIdParamName, clientIdParamName, groupIdParamName, productIdParamName,
|
||||
activeParamName, activationDateParamName, nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName,
|
||||
interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName,
|
||||
lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName));
|
||||
interestPostingPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName,
|
||||
minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName));
|
||||
|
||||
/**
|
||||
* 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,
|
||||
accountNoParamName, externalIdParamName, statusParamName, activationDateParamName, clientIdParamName, "clientName",
|
||||
groupIdParamName, "groupName", "savingsProductId", "savingsProductName", "currency", nominalAnnualInterestRateParamName,
|
||||
interestCompoundingPeriodTypeParamName, interestCalculationTypeParamName,
|
||||
interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName,
|
||||
lockinPeriodFrequencyTypeParamName, "summary", "transactions", "productOptions", "interestRatePeriodFrequencyTypeOptions",
|
||||
"lockinPeriodFrequencyTypeOptions"));
|
||||
interestCompoundingPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName,
|
||||
minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName, "summary",
|
||||
"transactions", "productOptions", "interestCompoundingPeriodTypeOptions", "interestPostingPeriodTypeOptions",
|
||||
"interestCalculationTypeOptions", "interestCalculationDaysInYearTypeOptions", "lockinPeriodFrequencyTypeOptions"));
|
||||
|
||||
public static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
|
||||
localeParamName, dateFormatParamName, transactionDateParamName, transactionAmountParamName));
|
||||
|
||||
+16
-7
@@ -35,6 +35,7 @@ import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPostingPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsDropdownReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsProductReadPlatformService;
|
||||
@@ -146,9 +147,12 @@ public class SavingsProductsApiResource {
|
||||
|
||||
private SavingsProductData handleTemplateRelatedData(final SavingsProductData savingsProduct) {
|
||||
|
||||
final EnumOptionData interestPeriodType = SavingsEnumerations
|
||||
final EnumOptionData interestCompoundingPeriodType = SavingsEnumerations
|
||||
.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.DAILY);
|
||||
|
||||
final EnumOptionData interestPostingPeriodType = SavingsEnumerations
|
||||
.interestPostingPeriodType(SavingsInterestPostingPeriodType.MONTHLY);
|
||||
|
||||
final EnumOptionData interestCalculationType = SavingsEnumerations
|
||||
.interestCalculationType(SavingsInterestCalculationType.DAILY_BALANCE);
|
||||
|
||||
@@ -161,9 +165,12 @@ public class SavingsProductsApiResource {
|
||||
currency = new ArrayList<CurrencyData>(currencyOptions).get(0);
|
||||
}
|
||||
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions = this.dropdownReadPlatformService
|
||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveCompoundingInterestPeriodTypeOptions();
|
||||
|
||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveInterestPostingPeriodTypeOptions();
|
||||
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveInterestCalculationTypeOptions();
|
||||
|
||||
@@ -175,12 +182,14 @@ public class SavingsProductsApiResource {
|
||||
|
||||
SavingsProductData savingsProductToReturn = null;
|
||||
if (savingsProduct != null) {
|
||||
savingsProductToReturn = SavingsProductData.withTemplate(savingsProduct, currencyOptions, interestPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
savingsProductToReturn = SavingsProductData.withTemplate(savingsProduct, currencyOptions, interestCompoundingPeriodTypeOptions,
|
||||
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
} else {
|
||||
savingsProductToReturn = SavingsProductData.template(currency, interestPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
savingsProductToReturn = SavingsProductData.template(currency, interestCompoundingPeriodType, interestPostingPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, currencyOptions, interestCompoundingPeriodTypeOptions,
|
||||
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
return savingsProductToReturn;
|
||||
|
||||
+35
-20
@@ -15,7 +15,6 @@ import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
/**
|
||||
* Immutable data object representing a savings account.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class SavingsAccountData {
|
||||
|
||||
private final Long id;
|
||||
@@ -32,6 +31,7 @@ public class SavingsAccountData {
|
||||
private final CurrencyData currency;
|
||||
private final BigDecimal nominalAnnualInterestRate;
|
||||
private final EnumOptionData interestCompoundingPeriodType;
|
||||
private final EnumOptionData interestPostingPeriodType;
|
||||
private final EnumOptionData interestCalculationType;
|
||||
private final EnumOptionData interestCalculationDaysInYearType;
|
||||
private final BigDecimal minRequiredOpeningBalance;
|
||||
@@ -40,39 +40,49 @@ public class SavingsAccountData {
|
||||
|
||||
// associations
|
||||
private final SavingsAccountSummaryData summary;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<SavingsAccountTransactionData> transactions;
|
||||
|
||||
// template
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<SavingsProductData> productOptions;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<EnumOptionData> interestPostingPeriodTypeOptions;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<EnumOptionData> interestCalculationTypeOptions;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
|
||||
|
||||
public static SavingsAccountData instance(final Long id, final String accountNo, final String externalId,
|
||||
final SavingsAccountStatusEnumData status, final LocalDate activationDate, final Long groupId, final String groupName,
|
||||
final Long clientId, final String clientName, final Long productId, final String productName, final CurrencyData currency,
|
||||
final BigDecimal interestRate, final EnumOptionData interestCompoundingPeriodType,
|
||||
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
|
||||
final EnumOptionData lockinPeriodFrequencyType, final SavingsAccountSummaryData summary) {
|
||||
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
|
||||
final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType, final SavingsAccountSummaryData summary) {
|
||||
|
||||
final Collection<SavingsProductData> productOptions = null;
|
||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||
|
||||
return new SavingsAccountData(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName,
|
||||
productId, productName, currency, interestRate, interestCompoundingPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, summary,
|
||||
productOptions, interestCompoundingPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
|
||||
productId, productName, currency, interestRate, interestCompoundingPeriodType, interestPostingPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, summary, productOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
public static SavingsAccountData withTemplateOptions(final SavingsAccountData account,
|
||||
final Collection<SavingsProductData> productOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
|
||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
||||
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,
|
||||
account.groupId, account.groupName, account.clientId, account.clientName, account.savingsProductId,
|
||||
account.savingsProductName, account.currency, account.nominalAnnualInterestRate, account.interestCompoundingPeriodType,
|
||||
account.interestCalculationType, account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance,
|
||||
account.lockinPeriodFrequency, account.lockinPeriodFrequencyType, account.summary, productOptions,
|
||||
interestCompoundingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions, transactions);
|
||||
account.interestPostingPeriodType, account.interestCalculationType, account.interestCalculationDaysInYearType,
|
||||
account.minRequiredOpeningBalance, account.lockinPeriodFrequency, account.lockinPeriodFrequencyType, account.summary,
|
||||
productOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
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 BigDecimal nominalAnnualInterestRate = null;
|
||||
final EnumOptionData interestPeriodType = null;
|
||||
final EnumOptionData interestPostingPeriodType = null;
|
||||
final EnumOptionData interestCalculationType = null;
|
||||
final EnumOptionData interestCalculationDaysInYearType = null;
|
||||
final BigDecimal minRequiredOpeningBalance = null;
|
||||
@@ -106,27 +117,29 @@ public class SavingsAccountData {
|
||||
final EnumOptionData lockinPeriodFrequencyType = null;
|
||||
final SavingsAccountSummaryData summary = null;
|
||||
final Collection<SavingsProductData> productOptions = null;
|
||||
final Collection<CurrencyData> currencyOptions = null;
|
||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||
|
||||
return new SavingsAccountData(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName,
|
||||
productId, productName, currency, nominalAnnualInterestRate, interestPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, summary,
|
||||
productOptions, interestCompoundingPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
|
||||
productId, productName, currency, nominalAnnualInterestRate, interestPeriodType, interestPostingPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, summary, productOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
private SavingsAccountData(final Long id, final String accountNo, final String externalId, final SavingsAccountStatusEnumData status,
|
||||
final LocalDate activationDate, final Long groupId, final String groupName, final Long clientId, final String clientName,
|
||||
final Long productId, final String productName, final CurrencyData currency, final BigDecimal nominalAnnualInterestRate,
|
||||
final EnumOptionData interestPeriodType, final EnumOptionData interestCalculationType,
|
||||
final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType, final SavingsAccountSummaryData summary,
|
||||
final EnumOptionData interestPeriodType, final EnumOptionData interestPostingPeriodType,
|
||||
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
|
||||
final EnumOptionData lockinPeriodFrequencyType, final SavingsAccountSummaryData summary,
|
||||
final Collection<SavingsProductData> productOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
|
||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<SavingsAccountTransactionData> transactions) {
|
||||
@@ -144,6 +157,7 @@ public class SavingsAccountData {
|
||||
this.currency = currency;
|
||||
this.nominalAnnualInterestRate = nominalAnnualInterestRate;
|
||||
this.interestCompoundingPeriodType = interestPeriodType;
|
||||
this.interestPostingPeriodType = interestPostingPeriodType;
|
||||
this.interestCalculationType = interestCalculationType;
|
||||
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType;
|
||||
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
|
||||
@@ -153,6 +167,7 @@ public class SavingsAccountData {
|
||||
|
||||
this.productOptions = productOptions;
|
||||
this.interestCompoundingPeriodTypeOptions = interestCompoundingPeriodTypeOptions;
|
||||
this.interestPostingPeriodTypeOptions = interestPostingPeriodTypeOptions;
|
||||
this.interestCalculationTypeOptions = interestCalculationTypeOptions;
|
||||
this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions;
|
||||
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
|
||||
|
||||
+39
-12
@@ -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.interestCalculationTypeParamName;
|
||||
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.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
@@ -98,16 +99,33 @@ public class SavingsAccountDataValidator {
|
||||
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
}
|
||||
|
||||
final Integer interestPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCompoundingPeriodTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestPeriodType).notNull().inMinMaxRange(1, 7);
|
||||
if (fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
|
||||
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);
|
||||
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull().inMinMaxRange(1, 2);
|
||||
if (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 });
|
||||
}
|
||||
|
||||
final Integer interestCalculationDaysInYearType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestCalculationDaysInYearTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType).notNull()
|
||||
.inOfTheseValues(360, 365);
|
||||
if (fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) {
|
||||
final Integer interestCalculationType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName,
|
||||
element);
|
||||
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)) {
|
||||
final BigDecimal minOpeningBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName,
|
||||
@@ -213,22 +231,31 @@ public class SavingsAccountDataValidator {
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
|
||||
final Integer interestPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(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 });
|
||||
}
|
||||
|
||||
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)) {
|
||||
final Integer interestCalculationType = fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull()
|
||||
.inMinMaxRange(1, 2);
|
||||
.isOneOfTheseValues(new Object[] { 1, 2 });
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(interestCalculationDaysInYearTypeParamName, element)) {
|
||||
final Integer interestCalculationDaysInYearType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestCalculationDaysInYearTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType)
|
||||
.notNull().inOfTheseValues(360, 365);
|
||||
.notNull().isOneOfTheseValues(360, 365);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
|
||||
|
||||
+43
-24
@@ -22,6 +22,7 @@ public class SavingsProductData {
|
||||
private final CurrencyData currency;
|
||||
private final BigDecimal nominalAnnualInterestRate;
|
||||
private final EnumOptionData interestCompoundingPeriodType;
|
||||
private final EnumOptionData interestPostingPeriodType;
|
||||
private final EnumOptionData interestCalculationType;
|
||||
private final EnumOptionData interestCalculationDaysInYearType;
|
||||
private final BigDecimal minRequiredOpeningBalance;
|
||||
@@ -34,6 +35,8 @@ public class SavingsProductData {
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<EnumOptionData> interestPostingPeriodTypeOptions;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<EnumOptionData> interestCalculationTypeOptions;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions;
|
||||
@@ -41,8 +44,10 @@ public class SavingsProductData {
|
||||
private final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
|
||||
|
||||
public static SavingsProductData template(final CurrencyData currency, final EnumOptionData interestCompoundingPeriodType,
|
||||
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
|
||||
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestPeriodTypeOptions,
|
||||
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
|
||||
final EnumOptionData interestCalculationDaysInYearType, final Collection<CurrencyData> currencyOptions,
|
||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
|
||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
|
||||
@@ -56,9 +61,10 @@ public class SavingsProductData {
|
||||
final EnumOptionData lockinPeriodFrequencyType = null;
|
||||
|
||||
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType, currencyOptions, interestCompoundingPeriodTypeOptions,
|
||||
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,33 +72,39 @@ public class SavingsProductData {
|
||||
* {@link SavingsProductData} data with further template data for dropdowns.
|
||||
*/
|
||||
public static SavingsProductData withTemplate(final SavingsProductData existingProduct, final Collection<CurrencyData> currencyOptions,
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions, final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
|
||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
|
||||
|
||||
return new SavingsProductData(existingProduct.id, existingProduct.name, existingProduct.description, existingProduct.currency,
|
||||
existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
|
||||
existingProduct.interestCalculationType, existingProduct.interestCalculationDaysInYearType,
|
||||
existingProduct.minRequiredOpeningBalance, existingProduct.lockinPeriodFrequency,
|
||||
existingProduct.lockinPeriodFrequencyType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
|
||||
existingProduct.interestCalculationDaysInYearType, existingProduct.minRequiredOpeningBalance,
|
||||
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType, currencyOptions,
|
||||
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
public static SavingsProductData instance(final Long id, final String name, final String description, final CurrencyData currency,
|
||||
final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
|
||||
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType) {
|
||||
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
|
||||
final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType) {
|
||||
|
||||
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> interestCalculationDaysInYearTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
|
||||
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType, currencyOptions, interestCompoundingPeriodTypeOptions,
|
||||
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
public static SavingsProductData lookup(final Long id, final String name) {
|
||||
@@ -101,6 +113,7 @@ public class SavingsProductData {
|
||||
final String description = null;
|
||||
final BigDecimal nominalAnnualInterestRate = null;
|
||||
final EnumOptionData interestCompoundingPeriodType = null;
|
||||
final EnumOptionData interestPostingPeriodType = null;
|
||||
final EnumOptionData interestCalculationType = null;
|
||||
final EnumOptionData interestCalculationDaysInYearType = null;
|
||||
final BigDecimal minRequiredOpeningBalance = null;
|
||||
@@ -108,23 +121,27 @@ public class SavingsProductData {
|
||||
final EnumOptionData lockinPeriodFrequencyType = 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> interestCalculationDaysInYearTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
|
||||
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, currencyOptions, interestPeriodTypeOptions, interestCalculationTypeOptions,
|
||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType, currencyOptions, interestCompoundingPeriodTypeOptions,
|
||||
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
private SavingsProductData(final Long id, final String name, final String description, final CurrencyData currency,
|
||||
final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
|
||||
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
|
||||
final EnumOptionData lockinPeriodFrequencyType, final Collection<CurrencyData> currencyOptions,
|
||||
final Collection<EnumOptionData> interestPeriodTypeOptions, final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
|
||||
final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType,
|
||||
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
|
||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
|
||||
this.id = id;
|
||||
@@ -133,6 +150,7 @@ public class SavingsProductData {
|
||||
this.currency = currency;
|
||||
this.nominalAnnualInterestRate = nominalAnnualInterestRate;
|
||||
this.interestCompoundingPeriodType = interestCompoundingPeriodType;
|
||||
this.interestPostingPeriodType = interestPostingPeriodType;
|
||||
this.interestCalculationType = interestCalculationType;
|
||||
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType;
|
||||
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
|
||||
@@ -140,7 +158,8 @@ public class SavingsProductData {
|
||||
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType;
|
||||
|
||||
this.currencyOptions = currencyOptions;
|
||||
this.interestCompoundingPeriodTypeOptions = interestPeriodTypeOptions;
|
||||
this.interestCompoundingPeriodTypeOptions = interestCompoundingPeriodTypeOptions;
|
||||
this.interestPostingPeriodTypeOptions = interestPostingPeriodTypeOptions;
|
||||
this.interestCalculationTypeOptions = interestCalculationTypeOptions;
|
||||
this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions;
|
||||
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
|
||||
|
||||
+13
-6
@@ -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.interestCalculationTypeParamName;
|
||||
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.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
@@ -66,21 +67,27 @@ public class SavingsProductDataValidator {
|
||||
final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerSansLocaleNamed(digitsAfterDecimalParamName, element);
|
||||
baseDataValidator.reset().parameter(digitsAfterDecimalParamName).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
|
||||
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
final BigDecimal nominalAnnualInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(nominalAnnualInterestRate).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer interestCompoundingPeriodType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestCompoundingPeriodTypeParamName, element);
|
||||
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);
|
||||
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(
|
||||
interestCalculationDaysInYearTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType).notNull()
|
||||
.inOfTheseValues(360, 365);
|
||||
.isOneOfTheseValues(360, 365);
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
|
||||
final BigDecimal minOpeningBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName,
|
||||
@@ -172,7 +179,7 @@ public class SavingsProductDataValidator {
|
||||
final Integer interestCalculationDaysInYearType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestCalculationDaysInYearTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType)
|
||||
.notNull().inOfTheseValues(360, 365);
|
||||
.notNull().isOneOfTheseValues(360, 365);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
|
||||
|
||||
+107
-13
@@ -94,6 +94,12 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
@Column(name = "interest_compounding_period_enum", nullable = false)
|
||||
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.
|
||||
*/
|
||||
@@ -107,13 +113,13 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
@Column(name = "interest_calculation_days_in_year_type_enum", nullable = false)
|
||||
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;
|
||||
|
||||
@Column(name = "lockin_period_frequency", nullable = false)
|
||||
@Column(name = "lockin_period_frequency", nullable = true)
|
||||
private Integer lockinPeriodFrequency;
|
||||
|
||||
@Column(name = "lockin_period_frequency_enum", nullable = false)
|
||||
@Column(name = "lockin_period_frequency_enum", nullable = true)
|
||||
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,
|
||||
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 Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
|
||||
final SavingsAccountStatusType status = SavingsAccountStatusType.UNACTIVATED;
|
||||
final LocalDate activationDate = null;
|
||||
return new SavingsAccount(client, group, product, accountNo, externalId, status, activationDate, interestRate, interestPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType);
|
||||
return new SavingsAccount(client, group, product, accountNo, externalId, status, activationDate, interestRate,
|
||||
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
|
||||
minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
}
|
||||
|
||||
private SavingsAccount(final Client client, final Group group, final SavingsProduct product, final String accountNo,
|
||||
final String externalId, final SavingsAccountStatusType status, final LocalDate activationDate, final BigDecimal interestRate,
|
||||
final SavingsCompoundingInterestPeriodType interestPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||
final String externalId, final SavingsAccountStatusType status, final LocalDate activationDate, final BigDecimal nominalAnnualInterestRate,
|
||||
final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
|
||||
final SavingsInterestPostingPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
this.client = client;
|
||||
@@ -175,8 +183,9 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
if (activationDate != null) {
|
||||
this.activationDate = activationDate.toDate();
|
||||
}
|
||||
this.nominalAnnualInterestRate = interestRate;
|
||||
this.interestCompoundingPeriodType = interestPeriodType.getValue();
|
||||
this.nominalAnnualInterestRate = nominalAnnualInterestRate;
|
||||
this.interestCompoundingPeriodType = interestCompoundingPeriodType.getValue();
|
||||
this.interestPostingPeriodType = interestPostingPeriodType.getValue();
|
||||
this.interestCalculationType = interestCalculationType.getValue();
|
||||
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType.getValue();
|
||||
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
|
||||
@@ -266,13 +275,47 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
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.
|
||||
*
|
||||
* Interest calculation is performed on-the-fly over all account
|
||||
* transactions.
|
||||
*/
|
||||
public void calculateInterest(final LocalDate interestCalculationEndDate) {
|
||||
public List<InterestCompoundingPeriodSummary> calculateInterest(final LocalDate interestCalculationUpToDate) {
|
||||
|
||||
// no openingBalance concept supported yet but probably will to allow
|
||||
// for migrations.
|
||||
@@ -287,7 +330,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
final SavingsCompoundingInterestPeriodType compoundingPeriodType = SavingsCompoundingInterestPeriodType
|
||||
.fromInt(this.interestCompoundingPeriodType);
|
||||
final List<LocalDateInterval> interestCompoundingPeriods = determineInterestCompoundingPeriods(getActivationLocalDate(),
|
||||
interestCalculationEndDate, compoundingPeriodType);
|
||||
interestCalculationUpToDate, compoundingPeriodType);
|
||||
|
||||
// determine opening balance, daily interest rate to apply, interest
|
||||
// due, interest to compound for each period
|
||||
@@ -295,6 +338,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
openingAccountBalance, this.nominalAnnualInterestRate, daysInYearType, interestCompoundingPeriods);
|
||||
|
||||
this.summary.updateFromInterestPeriodSummaries(currency, compoundingPeriods);
|
||||
|
||||
return compoundingPeriods;
|
||||
}
|
||||
|
||||
private List<InterestCompoundingPeriodSummary> determineInterestCompoundingPeriodSummaries(final Money openingAccountBalance,
|
||||
@@ -386,6 +431,55 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
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,
|
||||
final SavingsCompoundingInterestPeriodType interestPeriodType) {
|
||||
|
||||
|
||||
+20
-5
@@ -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.interestCalculationTypeParamName;
|
||||
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.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
@@ -90,22 +91,34 @@ public class SavingsAccountAssembler {
|
||||
if (command.parameterExists(nominalAnnualInterestRateParamName)) {
|
||||
interestRate = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName);
|
||||
} else {
|
||||
interestRate = product.interestRate();
|
||||
interestRate = product.nominalAnnualInterestRate();
|
||||
}
|
||||
|
||||
final boolean active = fromApiJsonHelper.extractBooleanNamed(activeParamName, element);
|
||||
final LocalDate activationDate = fromApiJsonHelper.extractLocalDateNamed(activationDateParamName, element);
|
||||
|
||||
SavingsCompoundingInterestPeriodType interestPeriodType = null;
|
||||
SavingsCompoundingInterestPeriodType interestCompoundingPeriodType = null;
|
||||
final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName);
|
||||
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;
|
||||
final Integer interestCalculationTypeValue = command.integerValueOfParameterNamed(interestCalculationTypeParamName);
|
||||
if (interestCalculationTypeValue != null) {
|
||||
interestCalculationType = SavingsInterestCalculationType.fromInt(interestCalculationTypeValue);
|
||||
} else {
|
||||
interestCalculationType = product.interestCalculationType();
|
||||
}
|
||||
|
||||
SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType = null;
|
||||
@@ -113,6 +126,8 @@ public class SavingsAccountAssembler {
|
||||
.integerValueOfParameterNamed(interestCalculationDaysInYearTypeParamName);
|
||||
if (interestCalculationDaysInYearTypeValue != null) {
|
||||
interestCalculationDaysInYearType = SavingsInterestCalculationDaysInYearType.fromInt(interestCalculationDaysInYearTypeValue);
|
||||
} else {
|
||||
interestCalculationDaysInYearType = product.interestCalculationDaysInYearType();
|
||||
}
|
||||
|
||||
BigDecimal minRequiredOpeningBalance = null;
|
||||
@@ -141,8 +156,8 @@ public class SavingsAccountAssembler {
|
||||
}
|
||||
|
||||
final SavingsAccount account = SavingsAccount.createNewAccount(client, group, product, accountNo, externalId, interestRate,
|
||||
interestPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
|
||||
minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
account.setHelpers(this.savingsAccountTransactionSummaryWrapper);
|
||||
|
||||
if (active) {
|
||||
|
||||
+56
@@ -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;
|
||||
}
|
||||
}
|
||||
+44
-11
@@ -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.interestCalculationTypeParamName;
|
||||
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.lockinPeriodFrequencyParamName;
|
||||
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
|
||||
* 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)
|
||||
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.
|
||||
*/
|
||||
@@ -71,23 +79,24 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
@Column(name = "interest_calculation_days_in_year_type_enum", nullable = false)
|
||||
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;
|
||||
|
||||
@Column(name = "lockin_period_frequency", nullable = false)
|
||||
@Column(name = "lockin_period_frequency", nullable = true)
|
||||
private Integer lockinPeriodFrequency;
|
||||
|
||||
@Column(name = "lockin_period_frequency_enum", nullable = false)
|
||||
@Column(name = "lockin_period_frequency_enum", nullable = true)
|
||||
private Integer lockinPeriodFrequencyType;
|
||||
|
||||
public static SavingsProduct createNew(final String name, final String description, final MonetaryCurrency currency,
|
||||
final BigDecimal interestRate, final SavingsCompoundingInterestPeriodType interestPeriodType,
|
||||
final SavingsInterestCalculationType interestCalculationType,
|
||||
final BigDecimal interestRate, final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
|
||||
final SavingsInterestPostingPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
|
||||
return new SavingsProduct(name, description, currency, interestRate, interestPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
return new SavingsProduct(name, description, currency, interestRate, interestCompoundingPeriodType, interestPostingPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType);
|
||||
}
|
||||
|
||||
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,
|
||||
final SavingsCompoundingInterestPeriodType interestPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||
final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
|
||||
final SavingsInterestPostingPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
|
||||
@@ -105,7 +115,8 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
|
||||
this.currency = currency;
|
||||
this.nominalAnnualInterestRate = interestRate;
|
||||
this.interestCompoundingPeriodType = interestPeriodType.getValue();
|
||||
this.interestCompoundingPeriodType = interestCompoundingPeriodType.getValue();
|
||||
this.interestPostingPeriodType = interestPostingPeriodType.getValue();
|
||||
this.interestCalculationType = interestCalculationType.getValue();
|
||||
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType.getValue();
|
||||
|
||||
@@ -125,10 +136,26 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
return this.currency.copy();
|
||||
}
|
||||
|
||||
public BigDecimal interestRate() {
|
||||
public BigDecimal nominalAnnualInterestRate() {
|
||||
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() {
|
||||
return this.minRequiredOpeningBalance;
|
||||
}
|
||||
@@ -193,6 +220,12 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
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)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestCalculationTypeParamName);
|
||||
actualChanges.put(interestCalculationTypeParamName, newValue);
|
||||
|
||||
+11
-3
@@ -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.interestCalculationTypeParamName;
|
||||
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.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
@@ -32,10 +33,16 @@ public class SavingsProductAssembler {
|
||||
|
||||
final BigDecimal interestRate = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName);
|
||||
|
||||
SavingsCompoundingInterestPeriodType interestPeriodType = null;
|
||||
SavingsCompoundingInterestPeriodType interestCompoundingPeriodType = null;
|
||||
final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName);
|
||||
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;
|
||||
@@ -60,7 +67,8 @@ public class SavingsProductAssembler {
|
||||
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);
|
||||
}
|
||||
}
|
||||
+26
@@ -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);
|
||||
}
|
||||
}
|
||||
+26
-15
@@ -30,6 +30,7 @@ import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPostingPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savings.exception.SavingsAccountNotFoundException;
|
||||
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("sa.nominal_annual_interest_rate as nominalAnnualInterestRate, ");
|
||||
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_days_in_year_type_enum as interestCalculationDaysInYearType, ");
|
||||
sqlBuilder.append("sa.min_required_opening_balance as minRequiredOpeningBalance, ");
|
||||
@@ -162,6 +164,9 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.fromInt(JdbcSupport.getInteger(rs,
|
||||
"interestCompoundingPeriodType")));
|
||||
|
||||
final EnumOptionData interestPostingPeriodType = SavingsEnumerations.interestPostingPeriodType(SavingsInterestPostingPeriodType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestPostingPeriodType")));
|
||||
|
||||
final EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(SavingsInterestCalculationType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestCalculationType")));
|
||||
|
||||
@@ -188,11 +193,10 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
final SavingsAccountSummaryData summary = new SavingsAccountSummaryData(currency, totalDeposits, totalWithdrawals,
|
||||
totalInterestEarned, totalInterestPosted, accountBalance);
|
||||
|
||||
return SavingsAccountData
|
||||
.instance(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName, productId,
|
||||
productName, currency, nominalAnnualInterestRate, interestCompoundingPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
|
||||
summary);
|
||||
return SavingsAccountData.instance(id, accountNo, externalId, status, activationDate, groupId, groupName, clientId, clientName,
|
||||
productId, productName, currency, nominalAnnualInterestRate, interestCompoundingPeriodType, interestPostingPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, summary);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,6 +227,9 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveCompoundingInterestPeriodTypeOptions();
|
||||
|
||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveInterestPostingPeriodTypeOptions();
|
||||
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveInterestCalculationTypeOptions();
|
||||
|
||||
@@ -234,8 +241,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||
|
||||
template = SavingsAccountData.withTemplateOptions(template, productOptions, interestCompoundingPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
|
||||
transactions);
|
||||
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions, transactions);
|
||||
} else {
|
||||
|
||||
String clientName = null;
|
||||
@@ -251,14 +258,15 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
template = SavingsAccountData.withClientTemplate(clientId, clientName, groupId, groupName);
|
||||
|
||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
|
||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||
|
||||
template = SavingsAccountData.withTemplateOptions(template, productOptions, interestCompoundingPeriodTypeOptions,
|
||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
|
||||
transactions);
|
||||
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
return template;
|
||||
@@ -391,6 +399,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
|
||||
sqlBuilder.append("sp.nominal_annual_interest_rate as nominalAnnualIterestRate, ");
|
||||
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_days_in_year_type_enum as interestCalculationDaysInYearType, ");
|
||||
sqlBuilder.append("sp.min_required_opening_balance as minRequiredOpeningBalance, ");
|
||||
@@ -422,9 +431,12 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
|
||||
final BigDecimal nominalAnnualIterestRate = rs.getBigDecimal("nominalAnnualIterestRate");
|
||||
|
||||
EnumOptionData interestPeriodType = SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType
|
||||
EnumOptionData interestCompoundingPeriodType = SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestCompoundingPeriodType")));
|
||||
|
||||
final EnumOptionData interestPostingPeriodType = SavingsEnumerations.interestPostingPeriodType(SavingsInterestPostingPeriodType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestPostingPeriodType")));
|
||||
|
||||
EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(SavingsInterestCalculationType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestCalculationType")));
|
||||
|
||||
@@ -459,11 +471,10 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
final SavingsAccountStatusEnumData status = null;
|
||||
final LocalDate activationDate = null;
|
||||
final SavingsAccountSummaryData summary = null;
|
||||
return SavingsAccountData
|
||||
.instance(null, null, null, status, activationDate, groupId, groupName, clientId, clientName, productId, productName,
|
||||
currency, nominalAnnualIterestRate, interestPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
|
||||
summary);
|
||||
return SavingsAccountData.instance(null, null, null, status, activationDate, groupId, groupName, clientId, clientName,
|
||||
productId, productName, currency, nominalAnnualIterestRate, interestCompoundingPeriodType, interestPostingPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, summary);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -23,4 +23,6 @@ public interface SavingsAccountWritePlatformService {
|
||||
CommandProcessingResult withdrawal(Long savingsId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult calculateInterest(Long savingsId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult postInterest(Long savingsId, JsonCommand command);
|
||||
}
|
||||
+19
@@ -334,4 +334,23 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
.withSavingsId(savingsId) //
|
||||
.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();
|
||||
}
|
||||
}
|
||||
+2
@@ -10,6 +10,8 @@ public interface SavingsDropdownReadPlatformService {
|
||||
|
||||
Collection<EnumOptionData> retrieveCompoundingInterestPeriodTypeOptions();
|
||||
|
||||
Collection<EnumOptionData> retrieveInterestPostingPeriodTypeOptions();
|
||||
|
||||
Collection<EnumOptionData> retrieveInterestCalculationTypeOptions();
|
||||
|
||||
Collection<EnumOptionData> retrieveInterestCalculationDaysInYearTypeOptions();
|
||||
|
||||
+13
@@ -8,6 +8,7 @@ import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPostingPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -42,6 +43,18 @@ public class SavingsDropdownReadPlatformServiceImpl implements SavingsDropdownRe
|
||||
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
|
||||
public Collection<EnumOptionData> retrieveInterestCalculationTypeOptions() {
|
||||
List<EnumOptionData> allowedOptions = Arrays.asList( //
|
||||
|
||||
+35
@@ -13,6 +13,7 @@ import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransactionType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPostingPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType;
|
||||
|
||||
public class SavingsEnumerations {
|
||||
@@ -109,6 +110,40 @@ public class SavingsEnumerations {
|
||||
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) {
|
||||
return compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.fromInt(type));
|
||||
}
|
||||
|
||||
+8
-2
@@ -19,6 +19,7 @@ import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestPostingPeriodType;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsPeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savings.exception.SavingsProductNotFoundException;
|
||||
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("sp.nominal_annual_interest_rate as nominalAnnualInterestRate, ");
|
||||
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_days_in_year_type_enum as interestCalculationDaysInYearType, ");
|
||||
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")));
|
||||
|
||||
SavingsInterestPostingPeriodType interestPostingPeriod = SavingsInterestPostingPeriodType.fromInt(JdbcSupport.getInteger(rs,
|
||||
"interestPostingPeriodType"));
|
||||
EnumOptionData interestPostingPeriodType = SavingsEnumerations.interestPostingPeriodType(interestPostingPeriod);
|
||||
|
||||
EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(SavingsInterestCalculationType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestCalculationType")));
|
||||
|
||||
@@ -140,8 +146,8 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
|
||||
}
|
||||
|
||||
return SavingsProductData.instance(id, name, description, currency, nominalAnnualInterestRate, compoundingInterestPeriodType,
|
||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType);
|
||||
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user