From 691e836c68973703fa82164abcba9aa70c1232a3 Mon Sep 17 00:00:00 2001 From: Madhukar Date: Thu, 20 Sep 2012 12:32:07 +0530 Subject: [PATCH] Interest Payouts --- .../api/DepositAccountsApiResource.java | 5 ++ ...DepositAccountWithdrawInterestCommand.java | 26 ++++++++++ .../api/data/DepositPermissionData.java | 9 ++-- .../ApiDataConversionService.java | 3 ++ .../ApiDataConversionServiceImpl.java | 23 +++++++++ .../ClientReadPlatformServiceImpl.java | 2 +- .../saving/domain/DepositAccount.java | 43 ++++++++++++---- .../saving/domain/DepositAccountStatus.java | 10 ++-- .../domain/DepositAccountTransaction.java | 20 ++++++-- .../DepositLifecycleStateMachineImpl.java | 10 ++-- .../service/DepositAccountEnumerations.java | 4 +- ...DepositAccountReadPlatformServiceImpl.java | 6 +-- ...ositAccountWithdrawalCommandValidator.java | 33 ++++++++++++ .../DepositAccountWritePlatformService.java | 9 ++-- ...WritePlatformServiceJpaRepositoryImpl.java | 50 +++++++++++++++++-- ...ateTransitionApprovalCommandValidator.java | 2 +- ...epositAccountInterestCommandValidator.java | 32 ++++++++++++ 17 files changed, 244 insertions(+), 43 deletions(-) create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositAccountWithdrawInterestCommand.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWithdrawalCommandValidator.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/saving/service/WithDrawDepositAccountInterestCommandValidator.java diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositAccountsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositAccountsApiResource.java index 92fcfb05e..d603be17f 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositAccountsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositAccountsApiResource.java @@ -21,6 +21,7 @@ import javax.ws.rs.core.UriInfo; import org.apache.commons.lang.StringUtils; import org.mifosng.platform.api.commands.DepositAccountCommand; +import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionCommand; @@ -201,6 +202,10 @@ public class DepositAccountsApiResource { DepositAccountWithdrawalCommand command = apiDataConversionService.convertJsonToDepositWithdrawalCommand(accountId, jsonRequestBody); EntityIdentifier identifier = this.depositAccountWritePlatformService.withdrawDepositAccountMoney(command); response = Response.ok().entity(identifier).build(); + } else if(is(commandParam, "interestwithdraw")){ + DepositAccountWithdrawInterestCommand command = apiDataConversionService.convertJsonToDepositAccountWithdrawInterestCommand(accountId, jsonRequestBody); + EntityIdentifier identifier = this.depositAccountWritePlatformService.withdrawDepositAccountInterestMoney(command); + response = Response.ok().entity(identifier).build(); } else { DepositStateTransitionCommand command=apiDataConversionService.convertJsonToDepositStateTransitionCommand(accountId, jsonRequestBody); if (is(commandParam, "reject")) { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositAccountWithdrawInterestCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositAccountWithdrawInterestCommand.java new file mode 100644 index 000000000..aebb3002e --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositAccountWithdrawInterestCommand.java @@ -0,0 +1,26 @@ +package org.mifosng.platform.api.commands; + +import java.math.BigDecimal; + +public class DepositAccountWithdrawInterestCommand { + + private final Long accountId; + private final BigDecimal withdrawInterest; + private final String note; + + public DepositAccountWithdrawInterestCommand(final Long accountId, BigDecimal withdrawInterest, String note){ + this.accountId=accountId; + this.withdrawInterest=withdrawInterest; + this.note=note; + } + + public Long getAccountId() { + return accountId; + } + public BigDecimal getWithdrawInterest() { + return withdrawInterest; + } + public String getNote() { + return note; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositPermissionData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositPermissionData.java index f58421745..b3637f4e5 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositPermissionData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositPermissionData.java @@ -6,17 +6,16 @@ public class DepositPermissionData { private final boolean withdrawnByApplicantAllowed; private final boolean undoApprovalAllowed; private final boolean pendingApproval; - private final boolean isActive; + //private final boolean isActive; private final boolean anyActionOnAccountAllowed; - public DepositPermissionData(final boolean rejectAllowed,final boolean withdrawnByApplicantAllowed,final boolean undoApprovalAllowed,final boolean pendingApproval,final boolean isActive) { + public DepositPermissionData(final boolean rejectAllowed,final boolean withdrawnByApplicantAllowed,final boolean undoApprovalAllowed,final boolean pendingApproval) { this.rejectAllowed = rejectAllowed; this.withdrawnByApplicantAllowed = withdrawnByApplicantAllowed; this.undoApprovalAllowed = undoApprovalAllowed; this.pendingApproval = pendingApproval; - this.isActive=isActive; this.anyActionOnAccountAllowed = isRejectAllowed() || isPendingApproval() || isUndoApprovalAllowed() || isWithdrawnByApplicantAllowed(); } @@ -40,7 +39,7 @@ public class DepositPermissionData { return anyActionOnAccountAllowed; } - public boolean isActive() { + /*public boolean isActive() { return isActive; - } + }*/ } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionService.java index cb9558cdb..b7d816b5b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionService.java @@ -5,6 +5,7 @@ import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; import org.mifosng.platform.api.commands.ChargeCommand; import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.api.commands.DepositAccountCommand; +import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; import org.mifosng.platform.api.commands.DepositProductCommand; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; @@ -72,4 +73,6 @@ public interface ApiDataConversionService { StaffCommand convertJsonToStaffCommand(Long resourceIdentifier, String json); DepositAccountWithdrawalCommand convertJsonToDepositWithdrawalCommand(Long resourceIdentifier, String jsonRequestBody); + + DepositAccountWithdrawInterestCommand convertJsonToDepositAccountWithdrawInterestCommand(Long resourceIdentifier, String jsonRequestBody); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java index 08e2dd90b..37f7e9755 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java @@ -22,6 +22,7 @@ import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; import org.mifosng.platform.api.commands.ChargeCommand; import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.api.commands.DepositAccountCommand; +import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; import org.mifosng.platform.api.commands.DepositProductCommand; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; @@ -1186,4 +1187,26 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService { return new DepositAccountWithdrawalCommand(resourceIdentifier,renewAccount, deposit, note); } + + @Override + public DepositAccountWithdrawInterestCommand convertJsonToDepositAccountWithdrawInterestCommand(final Long resourceIdentifier, final String json) { + + if (StringUtils.isBlank(json)) { + throw new InvalidJsonException(); + } + + Type typeOfMap = new TypeToken>(){}.getType(); + Map requestMap = gsonConverter.fromJson(json, typeOfMap); + + Set supportedParams = new HashSet(Arrays.asList("amount", "note", "locale")); + + checkForUnsupportedParameters(requestMap, supportedParams); + + Set modifiedParameters = new HashSet(); + + BigDecimal amount=extractBigDecimalParameter("amount", requestMap, modifiedParameters); + String note = extractStringParameter("note", requestMap, modifiedParameters); + + return new DepositAccountWithdrawInterestCommand(resourceIdentifier, amount, note); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java index da789c94e..664c496fc 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java @@ -208,7 +208,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService if (row.getAccountStatusId() == 100) { pendingApprovalDepositAccounts.add(row); - } else if (row.getAccountStatusId() == 200) { + } else if (row.getAccountStatusId() == 300) { approvedDepositAccounts.add(row); } } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccount.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccount.java index e504de8bb..d6d1badee 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccount.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccount.java @@ -259,9 +259,13 @@ public class DepositAccount extends AbstractAuditableCustom { this.interestAccrued = futureValueOnMaturity.minus(getDeposit()).getAmount(); this.total = futureValueOnMaturity.getAmount(); - DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.deposit(getDeposit(), getActualCommencementDate()); + DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.deposit(getDeposit(), getActualCommencementDate(),getAccuredInterest()); depositaccountTransaction.updateAccount(this); - this.depositaccountTransactions.add(depositaccountTransaction); + this.depositaccountTransactions.add(depositaccountTransaction);/* + + depositaccountTransaction = DepositAccountTransaction.deposit(getAccuredInterest(), getActualCommencementDate(), getAccuredInterest()); + depositaccountTransaction.updateAccount(this); + this.depositaccountTransactions.add(depositaccountTransaction);*/ LocalDate submittalDate = new LocalDate(this.projectedCommencementDate); if (actualCommencementDate.isBefore(submittalDate)) { @@ -387,6 +391,10 @@ public class DepositAccount extends AbstractAuditableCustom { return Money.of(this.currency, this.depositAmount); } + public Money getAccuredInterest(){ + return Money.of(this.currency, this.interestAccrued); + } + public Client client() { return this.client; } @@ -400,10 +408,18 @@ public class DepositAccount extends AbstractAuditableCustom { } public boolean isRenewalAllowed() { - return renewalAllowed; + return this.renewalAllowed; + } + + public Integer getTenureInMonths() { + return tenureInMonths; } - public void matureDepositApplication(LocalDate maturedOnDate, DepositLifecycleStateMachine depositLifecycleStateMachine) { + public Integer getInterestCompoundedEvery() { + return this.interestCompoundedEvery; + } + + /*public void matureDepositApplication(LocalDate maturedOnDate, DepositLifecycleStateMachine depositLifecycleStateMachine) { if (maturedOnDate.isAfter(maturesOnDate()) || (new LocalDate().equals(maturesOnDate()) && maturedOnDate.equals(maturesOnDate()))) { DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition( @@ -458,7 +474,7 @@ public class DepositAccount extends AbstractAuditableCustom { "cannot.manual.mature.deposit.account.date", errorMessage, maturedOnDate, new LocalDate()); } - } + }*/ public LocalDate maturesOnDate() { LocalDate date = null; @@ -481,9 +497,13 @@ public class DepositAccount extends AbstractAuditableCustom { DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_MATURED, DepositAccountStatus.fromInt(this.depositStatus)); this.depositStatus = statusEnum.getValue(); - DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(Money.of(this.currency, this.total), new LocalDate()); + DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(getDeposit(), new LocalDate(),getAccuredInterest()); depositaccountTransaction.updateAccount(this); - this.depositaccountTransactions.add(depositaccountTransaction); + this.depositaccountTransactions.add(depositaccountTransaction);/* + + depositaccountTransaction = DepositAccountTransaction.withdraw(getAccuredInterest(), new LocalDate(),getAccuredInterest()); + depositaccountTransaction.updateAccount(this); + this.depositaccountTransactions.add(depositaccountTransaction);*/ DepositAccountStatus statusEnumForClose = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CLOSED, DepositAccountStatus.fromInt(this.depositStatus)); this.depositStatus = statusEnumForClose.getValue(); @@ -497,9 +517,13 @@ public class DepositAccount extends AbstractAuditableCustom { DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_PRECLOSED, DepositAccountStatus.fromInt(this.depositStatus)); this.depositStatus = statusEnum.getValue(); - DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(Money.of(this.currency, this.total), new LocalDate()); + DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(getDeposit(), new LocalDate(),getAccuredInterest()); depositaccountTransaction.updateAccount(this); - this.depositaccountTransactions.add(depositaccountTransaction); + this.depositaccountTransactions.add(depositaccountTransaction);/* + + depositaccountTransaction = DepositAccountTransaction.withdraw(getAccuredInterest(), new LocalDate(),getAccuredInterest()); + depositaccountTransaction.updateAccount(this); + this.depositaccountTransactions.add(depositaccountTransaction);*/ this.closedOnDate = new LocalDate().toDate(); this.withdrawnOnDate = null; @@ -520,6 +544,7 @@ public class DepositAccount extends AbstractAuditableCustom { preClosureInterestRate, interestCompoundedEvery, this.product.getInterestCompoundedEveryPeriodType()); this.total = accuredtotalAmount.getAmount(); + this.interestAccrued = accuredtotalAmount.minus(deposit).getAmount(); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountStatus.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountStatus.java index f2cd31a95..3448d1837 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountStatus.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountStatus.java @@ -4,7 +4,7 @@ public enum DepositAccountStatus { INVALID(0, "depositStatusType.invalid"), // SUBMITED_AND_PENDING_APPROVAL(100, "depositStatusType.submitted.and.pending.approval"), // - APPROVED(200, "depositStatusType.approved"), // + //APPROVED(200, "depositStatusType.approved"), // ACTIVE(300, "depositStatusType.active"), // WITHDRAWN_BY_CLIENT(400, "depositStatusType.withdrawn.by.client"), // REJECTED(500, "depositStatusType.rejected"), // @@ -36,9 +36,9 @@ public enum DepositAccountStatus { return this.value.equals(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL.getValue()); } - public boolean isApproved() { + /*public boolean isApproved() { return this.value.equals(DepositAccountStatus.APPROVED.getValue()); - } + }*/ public boolean isActive() { return this.value.equals(DepositAccountStatus.ACTIVE.getValue()); @@ -67,9 +67,9 @@ public enum DepositAccountStatus { case 100: enumeration = DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL; break; - case 200: + /*case 200: enumeration = DepositAccountStatus.APPROVED; - break; + break;*/ case 300: enumeration = DepositAccountStatus.ACTIVE; break; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransaction.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransaction.java index e53ca194c..df67a48dc 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransaction.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransaction.java @@ -45,17 +45,27 @@ public class DepositAccountTransaction extends AbstractPersistable { @Column(name = "amount", scale = 6, precision = 19, nullable = false) private final BigDecimal amount; + @Column(name = "interest", scale = 6, precision = 19, nullable = false) + private final BigDecimal interest; + + @Column(name = "total", scale = 6, precision = 19, nullable = false) + private final BigDecimal total; + protected DepositAccountTransaction(){ this.depositAccount=null; this.typeOf=null; this.amount=null; this.dateOf=null; + this.interest=null; + this.total=null; } - private DepositAccountTransaction(DepositAccountTransactionType type, final BigDecimal amount, final LocalDate date) { + private DepositAccountTransaction(DepositAccountTransactionType type, final BigDecimal amount, final LocalDate date, final BigDecimal interest) { this.typeOf = type; this.amount = amount; this.dateOf = date.toDateMidnight().toDate(); + this.interest = interest; + this.total = amount.add(interest); } public Date getDateOf() { @@ -82,12 +92,12 @@ public class DepositAccountTransaction extends AbstractPersistable { return DepositAccountTransactionType.DEPOSIT.equals(typeOf); } - public static DepositAccountTransaction deposit(Money amount, LocalDate paymentDate) { - return new DepositAccountTransaction(DepositAccountTransactionType.DEPOSIT, amount.getAmount(), paymentDate); + public static DepositAccountTransaction deposit(Money amount, LocalDate paymentDate, Money interest) { + return new DepositAccountTransaction(DepositAccountTransactionType.DEPOSIT, amount.getAmount(), paymentDate, interest.getAmount()); } - public static DepositAccountTransaction withdraw(Money amount, LocalDate paymentDate) { - return new DepositAccountTransaction(DepositAccountTransactionType.WITHDRAW, amount.getAmount(), paymentDate); + public static DepositAccountTransaction withdraw(Money amount, LocalDate paymentDate, Money interest) { + return new DepositAccountTransaction(DepositAccountTransactionType.WITHDRAW, amount.getAmount(), paymentDate, interest.getAmount()); } public void updateAccount(DepositAccount depositAccount) { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositLifecycleStateMachineImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositLifecycleStateMachineImpl.java index 5a0f68226..a9411b410 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositLifecycleStateMachineImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositLifecycleStateMachineImpl.java @@ -35,7 +35,7 @@ public class DepositLifecycleStateMachineImpl implements break; case DEPOSIT_APPROVED: if (from.hasStateOf(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL)) { - newState = stateOf(DepositAccountStatus.APPROVED, allowedDepositStatuses); + newState = stateOf(DepositAccountStatus.ACTIVE, allowedDepositStatuses); } else{ final String errorMessage = "The DepositApplication can not be approved from "+from.getCode() ; @@ -43,7 +43,7 @@ public class DepositLifecycleStateMachineImpl implements } break; case DEPOSIT_WITHDRAWN: - if (this.anyOfAllowedWhenComingFrom(from, DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL, DepositAccountStatus.APPROVED)) { + if (this.anyOfAllowedWhenComingFrom(from, DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL, DepositAccountStatus.ACTIVE)) { newState = stateOf(DepositAccountStatus.WITHDRAWN_BY_CLIENT, allowedDepositStatuses); } else{ @@ -52,7 +52,7 @@ public class DepositLifecycleStateMachineImpl implements } break; case DEPOSIT_APPROVAL_UNDO: - if (from.hasStateOf(DepositAccountStatus.APPROVED)) { + if (from.hasStateOf(DepositAccountStatus.ACTIVE)) { newState = stateOf(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL, allowedDepositStatuses); } else{ @@ -61,7 +61,7 @@ public class DepositLifecycleStateMachineImpl implements } break; case DEPOSIT_MATURED: - if (from.hasStateOf(DepositAccountStatus.APPROVED) ){ + if (from.hasStateOf(DepositAccountStatus.ACTIVE) ){ newState = stateOf(DepositAccountStatus.MATURED, allowedDepositStatuses); } else{ @@ -79,7 +79,7 @@ public class DepositLifecycleStateMachineImpl implements } break; case DEPOSIT_PRECLOSED: - if (from.hasStateOf(DepositAccountStatus.APPROVED) ){ + if (from.hasStateOf(DepositAccountStatus.ACTIVE) ){ newState = stateOf(DepositAccountStatus.PRECLOSED, allowedDepositStatuses); } else{ diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountEnumerations.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountEnumerations.java index 1798ddb81..13eca4f0a 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountEnumerations.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountEnumerations.java @@ -15,9 +15,9 @@ public class DepositAccountEnumerations { case SUBMITED_AND_PENDING_APPROVAL: optionData = new EnumOptionData(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL.getValue().longValue(), DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL.getCode(), "Submitted and pending approval"); break; - case APPROVED: + /*case APPROVED: optionData = new EnumOptionData(DepositAccountStatus.APPROVED.getValue().longValue(), DepositAccountStatus.APPROVED.getCode(), "Approved"); - break; + break;*/ case ACTIVE: optionData = new EnumOptionData(DepositAccountStatus.ACTIVE.getValue().longValue(), DepositAccountStatus.ACTIVE.getCode(), "Active"); break; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformServiceImpl.java index a8d89aa7c..949be05bc 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformServiceImpl.java @@ -247,11 +247,11 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead @Override public DepositPermissionData retrieveDepositAccountsPermissions(DepositAccountData depositAccountData) { boolean pendingApproval = (depositAccountData.getStatus().getId().equals(100L)); - boolean undoApprovalAllowed = (depositAccountData.getStatus().getId().equals(200L)); - boolean isActive = (depositAccountData.getStatus().getId().equals(300L)); + boolean undoApprovalAllowed = (depositAccountData.getStatus().getId().equals(300L)); + //boolean isActive = (depositAccountData.getStatus().getId().equals(300L)); boolean rejectAllowed = pendingApproval; boolean withdrawnByApplicantAllowed = pendingApproval; - return new DepositPermissionData(rejectAllowed, withdrawnByApplicantAllowed, undoApprovalAllowed, pendingApproval,isActive); + return new DepositPermissionData(rejectAllowed, withdrawnByApplicantAllowed, undoApprovalAllowed, pendingApproval); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWithdrawalCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWithdrawalCommandValidator.java new file mode 100644 index 000000000..d7f942be0 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWithdrawalCommandValidator.java @@ -0,0 +1,33 @@ +package org.mifosng.platform.saving.service; + +import java.util.ArrayList; +import java.util.List; + +import org.mifosng.platform.DataValidatorBuilder; +import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; +import org.mifosng.platform.api.data.ApiParameterError; +import org.mifosng.platform.exceptions.PlatformApiDataValidationException; + +public class DepositAccountWithdrawalCommandValidator { + + private final DepositAccountWithdrawalCommand command; + public DepositAccountWithdrawalCommandValidator(final DepositAccountWithdrawalCommand command) { + this.command=command; + } + + public void validate(){ + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.transaction"); + + baseDataValidator.reset().parameter("accountId").value(command.getAccountId()).notNull().integerGreaterThanZero(); + baseDataValidator.reset().parameter("renewAccount").value(command.isRenewAccount()).notNull(); + baseDataValidator.reset().parameter("deposit").value(command.getDeposit()).ignoreIfNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("note").value(command.getNote()).notNull(); + + if (!dataValidationErrors.isEmpty()) { + throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); + } + + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformService.java index eac73f313..5b0a496bf 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformService.java @@ -1,6 +1,7 @@ package org.mifosng.platform.saving.service; import org.mifosng.platform.api.commands.DepositAccountCommand; +import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionCommand; @@ -28,11 +29,13 @@ public interface DepositAccountWritePlatformService { @PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_APPROVE_DEPOSIT_ROLE', 'CAN_APPROVE_DEPOSIT_IN_THE_PAST_ROLE')") EntityIdentifier undoDepositApproval(UndoStateTransitionCommand undoCommand); - @PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_APPROVE_DEPOSIT_ROLE', 'CAN_APPROVE_DEPOSIT_IN_THE_PAST_ROLE')") - EntityIdentifier matureDepositApplication(DepositStateTransitionCommand command); + /*@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_APPROVE_DEPOSIT_ROLE', 'CAN_APPROVE_DEPOSIT_IN_THE_PAST_ROLE')") + EntityIdentifier matureDepositApplication(DepositStateTransitionCommand command);*/ @PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_APPROVE_DEPOSIT_ROLE', 'CAN_APPROVE_DEPOSIT_IN_THE_PAST_ROLE')") EntityIdentifier withdrawDepositAccountMoney(DepositAccountWithdrawalCommand command); - + + @PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_APPROVE_DEPOSIT_ROLE', 'CAN_APPROVE_DEPOSIT_IN_THE_PAST_ROLE')") + EntityIdentifier withdrawDepositAccountInterestMoney(DepositAccountWithdrawInterestCommand command); } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java index e4f909d5f..3f61fd04d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java @@ -6,7 +6,9 @@ import java.util.List; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; +import org.joda.time.Months; import org.mifosng.platform.api.commands.DepositAccountCommand; +import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionCommand; @@ -238,7 +240,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo return new EntityIdentifier(account.getId()); } - @Transactional + /*@Transactional @Override public EntityIdentifier matureDepositApplication(DepositStateTransitionCommand command) { @@ -260,11 +262,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo account.matureDepositApplication(eventDate, defaultDepositLifecycleStateMachine()); this.depositAccountRepository.save(account); - /*if(account.isRenewalAllowed()){ + if(account.isRenewalAllowed()){ final DepositAccount renewedAccount = this.depositAccountAssembler.assembleFrom(account); this.depositAccountRepository.save(renewedAccount); return new EntityIdentifier(renewedAccount.getId()); //returns the new deposit application id - }*/ + } String noteText = command.getNote(); if (StringUtils.isNotBlank(noteText)) { @@ -273,7 +275,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo } return new EntityIdentifier(account.getId()); - } + }*/ @Transactional @Override @@ -281,6 +283,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo context.authenticatedUser(); + DepositAccountWithdrawalCommandValidator validator = new DepositAccountWithdrawalCommandValidator(command); + validator.validate(); + DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); @@ -312,4 +317,41 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo } return new EntityIdentifier(account.getId()); } + + @Transactional + @Override + public EntityIdentifier withdrawDepositAccountInterestMoney(DepositAccountWithdrawInterestCommand command) { + + context.authenticatedUser(); + + WithDrawDepositAccountInterestCommandValidator validator = new WithDrawDepositAccountInterestCommandValidator(command); + validator.validate(); + + DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); + if (account == null || account.isDeleted()) { + throw new DepositAccountNotFoundException(command.getAccountId()); + } + + BigDecimal actualInterestAccured = account.getAccuredInterest().getAmount(); + Integer tenure = account.getTenureInMonths(); + BigDecimal interstGettingForPeriod = actualInterestAccured.divide(new BigDecimal(tenure)); + + + Integer interestCompoundEvery = account.getInterestCompoundedEvery(); + LocalDate lastInterestTakenDate = account.getActualCommencementDate(); + LocalDate todaysDate = new LocalDate(); + Integer noOfMonthsforInterestCal = Months.monthsBetween(lastInterestTakenDate, todaysDate).getMonths(); + Integer noOfPeriods = noOfMonthsforInterestCal / interestCompoundEvery; + BigDecimal availableInterestAmountForWithDrawal = interstGettingForPeriod.multiply(new BigDecimal(noOfPeriods)); + Integer iswithdrawable = availableInterestAmountForWithDrawal.compareTo(command.getWithdrawInterest()); + + if(noOfPeriods > 0 ){ + + }else if(noOfPeriods <= 0){ + if(iswithdrawable==-1){ + throw new RuntimeException(); + } + } + return new EntityIdentifier(account.getId()); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositStateTransitionApprovalCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositStateTransitionApprovalCommandValidator.java index 9b1c27b66..713456b32 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositStateTransitionApprovalCommandValidator.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositStateTransitionApprovalCommandValidator.java @@ -25,7 +25,7 @@ public class DepositStateTransitionApprovalCommandValidator { baseDataValidator.reset().parameter("accountId").value(command.getAccountId()).notNull().integerGreaterThanZero(); baseDataValidator.reset().parameter("commencementDate").value(command.getEventDate()).notNull(); - baseDataValidator.reset().parameter("depositAmount").value(command.getDepositAmount()).ignoreIfNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("deposit").value(command.getDepositAmount()).ignoreIfNull().zeroOrPositiveAmount(); baseDataValidator.reset().parameter("tenureInMonths").value(command.getTenureInMonths()).ignoreIfNull().integerGreaterThanZero(); baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(command.getInterestCompoundedEveryPeriodType()).ignoreIfNull().inMinMaxRange(2, 2); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/WithDrawDepositAccountInterestCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/WithDrawDepositAccountInterestCommandValidator.java new file mode 100644 index 000000000..73438058b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/WithDrawDepositAccountInterestCommandValidator.java @@ -0,0 +1,32 @@ +package org.mifosng.platform.saving.service; + +import java.util.ArrayList; +import java.util.List; + +import org.mifosng.platform.DataValidatorBuilder; +import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; +import org.mifosng.platform.api.data.ApiParameterError; +import org.mifosng.platform.exceptions.PlatformApiDataValidationException; + +public class WithDrawDepositAccountInterestCommandValidator { + + private final DepositAccountWithdrawInterestCommand command; + + public WithDrawDepositAccountInterestCommandValidator(final DepositAccountWithdrawInterestCommand command) { + this.command=command; + } + + public void validate(){ + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.transaction"); + + baseDataValidator.reset().parameter("accountId").value(command.getAccountId()).notNull().integerGreaterThanZero(); + baseDataValidator.reset().parameter("amount").value(command.getWithdrawInterest()).notNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("note").value(command.getNote()).notNull(); + + if (!dataValidationErrors.isEmpty()) { + throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); + } + } + +}