diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java index 733a27a2a..62f27efd0 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java @@ -5,7 +5,7 @@ */ package org.mifosplatform.portfolio.client.data; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.activationDateParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.activatedOnDateParamName; import java.lang.reflect.Type; import java.util.ArrayList; @@ -314,8 +314,8 @@ public final class ClientDataValidator { final JsonElement element = command.parsedJson(); - final LocalDate activationDate = this.fromApiJsonHelper.extractLocalDateNamed(activationDateParamName, element); - baseDataValidator.reset().parameter(activationDateParamName).value(activationDate).notNull(); + final LocalDate activationDate = this.fromApiJsonHelper.extractLocalDateNamed(activatedOnDateParamName, element); + baseDataValidator.reset().parameter(activatedOnDateParamName).value(activationDate).notNull(); throwExceptionIfValidationWarningsExist(dataValidationErrors); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/SavingsApiConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/SavingsApiConstants.java index 6fd7be0b2..1d24bdf7e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/SavingsApiConstants.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/SavingsApiConstants.java @@ -35,7 +35,7 @@ public class SavingsApiConstants { public static final String fieldOfficerIdParamName = "fieldOfficerId"; public static final String submittedOnDateParamName = "submittedOnDate"; public static final String activeParamName = "active"; - public static final String activationDateParamName = "activatedOnDate"; + public static final String activatedOnDateParamName = "activatedOnDate"; public static final String nameParamName = "name"; public static final String descriptionParamName = "description"; public static final String currencyCodeParamName = "currencyCode"; @@ -103,7 +103,7 @@ public class SavingsApiConstants { * parameters to match those of request parameters. */ public static final Set SAVINGS_ACCOUNT_RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList(idParamName, - accountNoParamName, externalIdParamName, statusParamName, activationDateParamName, clientIdParamName, "clientName", + accountNoParamName, externalIdParamName, statusParamName, activatedOnDateParamName, clientIdParamName, "clientName", groupIdParamName, "groupName", "savingsProductId", "savingsProductName", "currency", nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName, @@ -120,5 +120,5 @@ public class SavingsApiConstants { "accountId", accountNoParamName, "currency", "amount")); public static final Set SAVINGS_ACCOUNT_ACTIVATION_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList(localeParamName, - dateFormatParamName, activationDateParamName)); + dateFormatParamName, activatedOnDateParamName)); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/api/SavingsAccountsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/api/SavingsAccountsApiResource.java index a82b536c0..14f7dab0b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/api/SavingsAccountsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/api/SavingsAccountsApiResource.java @@ -31,21 +31,16 @@ import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformSer import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; -import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException; import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; import org.mifosplatform.infrastructure.core.service.Page; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.portfolio.group.service.SearchParameters; import org.mifosplatform.portfolio.savings.SavingsApiConstants; import org.mifosplatform.portfolio.savings.data.SavingsAccountData; import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData; -import org.mifosplatform.portfolio.savings.data.SavingsProductData; import org.mifosplatform.portfolio.savings.service.SavingsAccountReadPlatformService; -import org.mifosplatform.portfolio.savings.service.SavingsDropdownReadPlatformService; -import org.mifosplatform.portfolio.savings.service.SavingsProductReadPlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -57,8 +52,6 @@ import org.springframework.util.CollectionUtils; public class SavingsAccountsApiResource { private final SavingsAccountReadPlatformService savingsAccountReadPlatformService; - private final SavingsProductReadPlatformService savingsProductReadPlatformService; - private final SavingsDropdownReadPlatformService dropdownReadPlatformService; private final PlatformSecurityContext context; private final DefaultToApiJsonSerializer toApiJsonSerializer; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; @@ -66,14 +59,10 @@ public class SavingsAccountsApiResource { @Autowired public SavingsAccountsApiResource(final SavingsAccountReadPlatformService savingsAccountReadPlatformService, - final SavingsProductReadPlatformService savingsProductReadPlatformService, - final SavingsDropdownReadPlatformService dropdownReadPlatformService, final PlatformSecurityContext context, - final DefaultToApiJsonSerializer toApiJsonSerializer, + final PlatformSecurityContext context, final DefaultToApiJsonSerializer toApiJsonSerializer, final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, final ApiRequestParameterHelper apiRequestParameterHelper) { this.savingsAccountReadPlatformService = savingsAccountReadPlatformService; - this.savingsProductReadPlatformService = savingsProductReadPlatformService; - this.dropdownReadPlatformService = dropdownReadPlatformService; this.context = context; this.toApiJsonSerializer = toApiJsonSerializer; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; @@ -132,15 +121,17 @@ public class SavingsAccountsApiResource { @Path("{accountId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveOne(@PathParam("accountId") final Long accountId, @Context final UriInfo uriInfo) { + public String retrieveOne(@PathParam("accountId") final Long accountId, + @DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly, + @Context final UriInfo uriInfo) { context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME); final SavingsAccountData savingsAccount = this.savingsAccountReadPlatformService.retrieveOne(accountId); final Set mandatoryResponseParameters = new HashSet(); - SavingsAccountData savingsAccountTemplate = populateTemplateAndAssociations(accountId, savingsAccount, uriInfo, - mandatoryResponseParameters); + SavingsAccountData savingsAccountTemplate = populateTemplateAndAssociations(accountId, savingsAccount, staffInSelectedOfficeOnly, + uriInfo, mandatoryResponseParameters); final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters(), mandatoryResponseParameters); @@ -149,17 +140,9 @@ public class SavingsAccountsApiResource { } private SavingsAccountData populateTemplateAndAssociations(final Long accountId, final SavingsAccountData savingsAccount, - final UriInfo uriInfo, final Set mandatoryResponseParameters) { + final boolean staffInSelectedOfficeOnly, final UriInfo uriInfo, final Set mandatoryResponseParameters) { Collection transactions = null; - Collection productOptions = null; - Collection fieldOfficerOptions = null; - Collection interestCompoundingPeriodTypeOptions = null; - Collection interestCompoundingPostingTypeOptions = null; - Collection interestCalculationTypeOptions = null; - Collection interestCalculationDaysInYearTypeOptions = null; - Collection lockinPeriodFrequencyTypeOptions = null; - Collection withdrawalFeeTypeOptions = null; final Set associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters()); if (!associationParameters.isEmpty()) { @@ -178,52 +161,15 @@ public class SavingsAccountsApiResource { } } + SavingsAccountData templateData = null; final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); if (settings.isTemplate()) { - productOptions = this.savingsProductReadPlatformService.retrieveAllForLookup(); - // FIXME - FOR CHANGE SAVINGS ACCOUNT APPLICATION need to determine - // office id of savings account - // if (savingsAccount.officeId() != null) { - // - // if (staffInSelectedOfficeOnly) { - // // only bring back loan officers in selected branch/office - // Collection fieldOfficersInBranch = - // this.staffReadPlatformService - // .retrieveAllLoanOfficersInOfficeById(officeId); - // - // if (!CollectionUtils.isEmpty(fieldOfficersInBranch)) { - // fieldOfficerOptions = new - // ArrayList(fieldOfficersInBranch); - // } - // } else { - // // by default bring back all officers in selected - // // branch/office as well as officers in office above - // // this office - // final boolean restrictToLoanOfficersOnly = true; - // Collection loanOfficersInHierarchy = - // this.staffReadPlatformService - // .retrieveAllStaffInOfficeAndItsParentOfficeHierarchy(officeId, - // restrictToLoanOfficersOnly); - // - // if (!CollectionUtils.isEmpty(loanOfficersInHierarchy)) { - // fieldOfficerOptions = new - // ArrayList(loanOfficersInHierarchy); - // } - // } - // } - - interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService.retrieveCompoundingInterestPeriodTypeOptions(); - interestCompoundingPostingTypeOptions = this.dropdownReadPlatformService.retrieveInterestPostingPeriodTypeOptions(); - interestCalculationTypeOptions = this.dropdownReadPlatformService.retrieveInterestCalculationTypeOptions(); - interestCalculationDaysInYearTypeOptions = this.dropdownReadPlatformService.retrieveInterestCalculationDaysInYearTypeOptions(); - lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveLockinPeriodFrequencyTypeOptions(); - withdrawalFeeTypeOptions = this.dropdownReadPlatformService.retrievewithdrawalFeeTypeOptions(); + templateData = this.savingsAccountReadPlatformService.retrieveTemplate(savingsAccount.clientId(), savingsAccount.groupId(), + savingsAccount.productId(), staffInSelectedOfficeOnly); } - return SavingsAccountData.withTemplateOptions(savingsAccount, productOptions, fieldOfficerOptions, - interestCompoundingPeriodTypeOptions, interestCompoundingPostingTypeOptions, interestCalculationTypeOptions, - interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions); + return SavingsAccountData.withTemplateOptions(savingsAccount, templateData, transactions); } @PUT diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/SavingsAccountData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/SavingsAccountData.java index fcd1e5a58..796d4c271 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/SavingsAccountData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/SavingsAccountData.java @@ -28,8 +28,8 @@ public class SavingsAccountData { private final String clientName; private final Long savingsProductId; private final String savingsProductName; - private final Long fieldofficerId; - private final String fieldofficerName; + private final Long fieldOfficerId; + private final String fieldOfficerName; private final SavingsAccountStatusEnumData status; private final SavingsAccountApplicationTimelineData timeline; private final CurrencyData currency; @@ -53,21 +53,13 @@ public class SavingsAccountData { private final Collection transactions; // template - @SuppressWarnings("unused") private final Collection productOptions; - @SuppressWarnings("unused") private final Collection fieldOfficerOptions; - @SuppressWarnings("unused") private final Collection interestCompoundingPeriodTypeOptions; - @SuppressWarnings("unused") private final Collection interestPostingPeriodTypeOptions; - @SuppressWarnings("unused") private final Collection interestCalculationTypeOptions; - @SuppressWarnings("unused") private final Collection interestCalculationDaysInYearTypeOptions; - @SuppressWarnings("unused") private final Collection lockinPeriodFrequencyTypeOptions; - @SuppressWarnings("unused") private final Collection withdrawalFeeTypeOptions; public static SavingsAccountData instance(final Long id, final String accountNo, final String externalId, final Long groupId, @@ -101,6 +93,36 @@ public class SavingsAccountData { interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions); } + public static SavingsAccountData withTemplateOptions(final SavingsAccountData account, final SavingsAccountData template, + final Collection transactions) { + + if (template == null) { + final Collection productOptions = null; + final Collection fieldOfficerOptions = null; + final Collection interestCompoundingPeriodTypeOptions = null; + final Collection interestPostingPeriodTypeOptions = null; + final Collection interestCalculationTypeOptions = null; + final Collection interestCalculationDaysInYearTypeOptions = null; + final Collection lockinPeriodFrequencyTypeOptions = null; + final Collection withdrawalFeeTypeOptions = null; + + return withTemplateOptions(account, productOptions, fieldOfficerOptions, interestCompoundingPeriodTypeOptions, + interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, + lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions); + } + + return new SavingsAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName, + account.clientId, account.clientName, account.savingsProductId, account.savingsProductName, account.fieldOfficerId, + account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate, + account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType, + account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency, + account.lockinPeriodFrequencyType, account.withdrawalFeeAmount, account.withdrawalFeeType, account.annualFeeAmount, + account.annualFeeOnMonthDay, account.annualFeeNextDueDate, account.summary, transactions, template.productOptions, + template.fieldOfficerOptions, template.interestCompoundingPeriodTypeOptions, template.interestPostingPeriodTypeOptions, + template.interestCalculationTypeOptions, template.interestCalculationDaysInYearTypeOptions, + template.lockinPeriodFrequencyTypeOptions, template.withdrawalFeeTypeOptions); + } + public static SavingsAccountData withTemplateOptions(final SavingsAccountData account, final Collection productOptions, final Collection fieldOfficerOptions, final Collection interestCompoundingPeriodTypeOptions, @@ -111,8 +133,8 @@ public class SavingsAccountData { final Collection transactions) { return new SavingsAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName, - account.clientId, account.clientName, account.savingsProductId, account.savingsProductName, account.fieldofficerId, - account.fieldofficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate, + account.clientId, account.clientName, account.savingsProductId, account.savingsProductName, account.fieldOfficerId, + account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate, account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType, account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency, account.lockinPeriodFrequencyType, account.withdrawalFeeAmount, account.withdrawalFeeType, account.annualFeeAmount, @@ -194,8 +216,8 @@ public class SavingsAccountData { this.clientName = clientName; this.savingsProductId = productId; this.savingsProductName = productName; - this.fieldofficerId = fieldofficerId; - this.fieldofficerName = fieldofficerName; + this.fieldOfficerId = fieldofficerId; + this.fieldOfficerName = fieldofficerName; this.status = status; this.timeline = timeline; this.currency = currency; @@ -225,4 +247,16 @@ public class SavingsAccountData { this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions; this.withdrawalFeeTypeOptions = withdrawalFeeTypeOptions; } + + public Long clientId() { + return this.clientId; + } + + public Long groupId() { + return this.groupId; + } + + public Long productId() { + return this.savingsProductId; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/SavingsAccountTransactionDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/SavingsAccountTransactionDataValidator.java index 5f2eae32f..3ce43134a 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/SavingsAccountTransactionDataValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/SavingsAccountTransactionDataValidator.java @@ -5,7 +5,7 @@ */ package org.mifosplatform.portfolio.savings.data; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.activationDateParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.activatedOnDateParamName; import static org.mifosplatform.portfolio.savings.SavingsApiConstants.bankNumberParamName; import static org.mifosplatform.portfolio.savings.SavingsApiConstants.checkNumberParamName; import static org.mifosplatform.portfolio.savings.SavingsApiConstants.paymentTypeIdParamName; @@ -100,8 +100,8 @@ public class SavingsAccountTransactionDataValidator { final JsonElement element = command.parsedJson(); - final LocalDate activationDate = fromApiJsonHelper.extractLocalDateNamed(activationDateParamName, element); - baseDataValidator.reset().parameter(activationDateParamName).value(activationDate).notNull(); + final LocalDate activationDate = fromApiJsonHelper.extractLocalDateNamed(activatedOnDateParamName, element); + baseDataValidator.reset().parameter(activatedOnDateParamName).value(activationDate).notNull(); throwExceptionIfValidationWarningsExist(dataValidationErrors); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java index f64be5009..514b8167e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java @@ -1363,10 +1363,13 @@ public class SavingsAccount extends AbstractPersistable { final Locale locale = command.extractLocale(); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); - final LocalDate activationDate = command.localDateValueOfParameterNamed("activationDate"); + final LocalDate activationDate = command.localDateValueOfParameterNamed(SavingsApiConstants.activatedOnDateParamName); this.status = SavingsAccountStatusType.ACTIVE.getValue(); - actualChanges.put("status", SavingsEnumerations.status(this.status)); + actualChanges.put(SavingsApiConstants.statusParamName, SavingsEnumerations.status(this.status)); + actualChanges.put(SavingsApiConstants.localeParamName, command.locale()); + actualChanges.put(SavingsApiConstants.dateFormatParamName, command.dateFormat()); + actualChanges.put(SavingsApiConstants.activatedOnDateParamName, activationDate.toString(fmt)); this.rejectedOnDate = null; this.rejectedBy = null; @@ -1378,10 +1381,6 @@ public class SavingsAccount extends AbstractPersistable { this.activatedBy = currentUser; this.lockedInUntilDate = calculateDateAccountIsLockedUntil(getActivationLocalDate()); - actualChanges.put("locale", command.locale()); - actualChanges.put("dateFormat", command.dateFormat()); - actualChanges.put("activationDate", activationDate.toString(fmt)); - if (this.client.isActivatedAfter(activationDate)) { final String errorMessage = "The date on which a savings account is activate cannot be before its client activated date: " + this.client.getActivationLocalDate().toString(); @@ -1393,13 +1392,13 @@ public class SavingsAccount extends AbstractPersistable { if (activationDate.isBefore(submittalDate)) { final String errorMessage = "Savings account application cannot be withdrawn by applicant on date before its submittal date: " + submittalDate.toString(); - throw new InvalidSavingsAccountStateTransitionException("withdrawnByApplicant", "cannot.be.before.submittal.date", + throw new InvalidSavingsAccountStateTransitionException("activate", "cannot.be.before.submittal.date", errorMessage, getApprovedOnLocalDate(), submittalDate); } if (activationDate.isAfter(tenantsTodayDate)) { final String errorMessage = "Savings account application cannot be withdrawn by applicant on date in the future."; - throw new InvalidSavingsAccountStateTransitionException("withdrawnByApplicant", "cannot.be.a.future.date", errorMessage, + throw new InvalidSavingsAccountStateTransitionException("activate", "cannot.be.a.future.date", errorMessage, getApprovedOnLocalDate()); }