Interest Payouts

This commit is contained in:
Madhukar
2012-09-21 20:53:47 +05:30
parent 3a89d10454
commit 691e836c68
17 changed files with 244 additions and 43 deletions
@@ -21,6 +21,7 @@ import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.mifosng.platform.api.commands.DepositAccountCommand; 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.DepositAccountWithdrawalCommand;
import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand;
import org.mifosng.platform.api.commands.DepositStateTransitionCommand; import org.mifosng.platform.api.commands.DepositStateTransitionCommand;
@@ -201,6 +202,10 @@ public class DepositAccountsApiResource {
DepositAccountWithdrawalCommand command = apiDataConversionService.convertJsonToDepositWithdrawalCommand(accountId, jsonRequestBody); DepositAccountWithdrawalCommand command = apiDataConversionService.convertJsonToDepositWithdrawalCommand(accountId, jsonRequestBody);
EntityIdentifier identifier = this.depositAccountWritePlatformService.withdrawDepositAccountMoney(command); EntityIdentifier identifier = this.depositAccountWritePlatformService.withdrawDepositAccountMoney(command);
response = Response.ok().entity(identifier).build(); 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 { } else {
DepositStateTransitionCommand command=apiDataConversionService.convertJsonToDepositStateTransitionCommand(accountId, jsonRequestBody); DepositStateTransitionCommand command=apiDataConversionService.convertJsonToDepositStateTransitionCommand(accountId, jsonRequestBody);
if (is(commandParam, "reject")) { if (is(commandParam, "reject")) {
@@ -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;
}
}
@@ -6,17 +6,16 @@ public class DepositPermissionData {
private final boolean withdrawnByApplicantAllowed; private final boolean withdrawnByApplicantAllowed;
private final boolean undoApprovalAllowed; private final boolean undoApprovalAllowed;
private final boolean pendingApproval; private final boolean pendingApproval;
private final boolean isActive; //private final boolean isActive;
private final boolean anyActionOnAccountAllowed; 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.rejectAllowed = rejectAllowed;
this.withdrawnByApplicantAllowed = withdrawnByApplicantAllowed; this.withdrawnByApplicantAllowed = withdrawnByApplicantAllowed;
this.undoApprovalAllowed = undoApprovalAllowed; this.undoApprovalAllowed = undoApprovalAllowed;
this.pendingApproval = pendingApproval; this.pendingApproval = pendingApproval;
this.isActive=isActive;
this.anyActionOnAccountAllowed = isRejectAllowed() || isPendingApproval() || isUndoApprovalAllowed() || isWithdrawnByApplicantAllowed(); this.anyActionOnAccountAllowed = isRejectAllowed() || isPendingApproval() || isUndoApprovalAllowed() || isWithdrawnByApplicantAllowed();
} }
@@ -40,7 +39,7 @@ public class DepositPermissionData {
return anyActionOnAccountAllowed; return anyActionOnAccountAllowed;
} }
public boolean isActive() { /*public boolean isActive() {
return isActive; return isActive;
} }*/
} }
@@ -5,6 +5,7 @@ import org.mifosng.platform.api.commands.BranchMoneyTransferCommand;
import org.mifosng.platform.api.commands.ChargeCommand; import org.mifosng.platform.api.commands.ChargeCommand;
import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.api.commands.ClientCommand;
import org.mifosng.platform.api.commands.DepositAccountCommand; 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.DepositAccountWithdrawalCommand;
import org.mifosng.platform.api.commands.DepositProductCommand; import org.mifosng.platform.api.commands.DepositProductCommand;
import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand;
@@ -72,4 +73,6 @@ public interface ApiDataConversionService {
StaffCommand convertJsonToStaffCommand(Long resourceIdentifier, String json); StaffCommand convertJsonToStaffCommand(Long resourceIdentifier, String json);
DepositAccountWithdrawalCommand convertJsonToDepositWithdrawalCommand(Long resourceIdentifier, String jsonRequestBody); DepositAccountWithdrawalCommand convertJsonToDepositWithdrawalCommand(Long resourceIdentifier, String jsonRequestBody);
DepositAccountWithdrawInterestCommand convertJsonToDepositAccountWithdrawInterestCommand(Long resourceIdentifier, String jsonRequestBody);
} }
@@ -22,6 +22,7 @@ import org.mifosng.platform.api.commands.BranchMoneyTransferCommand;
import org.mifosng.platform.api.commands.ChargeCommand; import org.mifosng.platform.api.commands.ChargeCommand;
import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.api.commands.ClientCommand;
import org.mifosng.platform.api.commands.DepositAccountCommand; 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.DepositAccountWithdrawalCommand;
import org.mifosng.platform.api.commands.DepositProductCommand; import org.mifosng.platform.api.commands.DepositProductCommand;
import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand;
@@ -1186,4 +1187,26 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
return new DepositAccountWithdrawalCommand(resourceIdentifier,renewAccount, deposit, note); 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<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(Arrays.asList("amount", "note", "locale"));
checkForUnsupportedParameters(requestMap, supportedParams);
Set<String> modifiedParameters = new HashSet<String>();
BigDecimal amount=extractBigDecimalParameter("amount", requestMap, modifiedParameters);
String note = extractStringParameter("note", requestMap, modifiedParameters);
return new DepositAccountWithdrawInterestCommand(resourceIdentifier, amount, note);
}
} }
@@ -208,7 +208,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
if (row.getAccountStatusId() == 100) { if (row.getAccountStatusId() == 100) {
pendingApprovalDepositAccounts.add(row); pendingApprovalDepositAccounts.add(row);
} else if (row.getAccountStatusId() == 200) { } else if (row.getAccountStatusId() == 300) {
approvedDepositAccounts.add(row); approvedDepositAccounts.add(row);
} }
} }
@@ -259,9 +259,13 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
this.interestAccrued = futureValueOnMaturity.minus(getDeposit()).getAmount(); this.interestAccrued = futureValueOnMaturity.minus(getDeposit()).getAmount();
this.total = futureValueOnMaturity.getAmount(); this.total = futureValueOnMaturity.getAmount();
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.deposit(getDeposit(), getActualCommencementDate()); DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.deposit(getDeposit(), getActualCommencementDate(),getAccuredInterest());
depositaccountTransaction.updateAccount(this); 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); LocalDate submittalDate = new LocalDate(this.projectedCommencementDate);
if (actualCommencementDate.isBefore(submittalDate)) { if (actualCommencementDate.isBefore(submittalDate)) {
@@ -387,6 +391,10 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
return Money.of(this.currency, this.depositAmount); return Money.of(this.currency, this.depositAmount);
} }
public Money getAccuredInterest(){
return Money.of(this.currency, this.interestAccrued);
}
public Client client() { public Client client() {
return this.client; return this.client;
} }
@@ -400,10 +408,18 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
} }
public boolean isRenewalAllowed() { public boolean isRenewalAllowed() {
return renewalAllowed; return this.renewalAllowed;
} }
public void matureDepositApplication(LocalDate maturedOnDate, DepositLifecycleStateMachine depositLifecycleStateMachine) { public Integer getTenureInMonths() {
return tenureInMonths;
}
public Integer getInterestCompoundedEvery() {
return this.interestCompoundedEvery;
}
/*public void matureDepositApplication(LocalDate maturedOnDate, DepositLifecycleStateMachine depositLifecycleStateMachine) {
if (maturedOnDate.isAfter(maturesOnDate()) || (new LocalDate().equals(maturesOnDate()) && maturedOnDate.equals(maturesOnDate()))) { if (maturedOnDate.isAfter(maturesOnDate()) || (new LocalDate().equals(maturesOnDate()) && maturedOnDate.equals(maturesOnDate()))) {
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition( DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(
@@ -458,7 +474,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
"cannot.manual.mature.deposit.account.date", errorMessage, "cannot.manual.mature.deposit.account.date", errorMessage,
maturedOnDate, new LocalDate()); maturedOnDate, new LocalDate());
} }
} }*/
public LocalDate maturesOnDate() { public LocalDate maturesOnDate() {
LocalDate date = null; LocalDate date = null;
@@ -481,9 +497,13 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_MATURED, DepositAccountStatus.fromInt(this.depositStatus)); DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_MATURED, DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnum.getValue(); 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); 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)); DepositAccountStatus statusEnumForClose = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CLOSED, DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnumForClose.getValue(); this.depositStatus = statusEnumForClose.getValue();
@@ -497,9 +517,13 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_PRECLOSED, DepositAccountStatus.fromInt(this.depositStatus)); DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_PRECLOSED, DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnum.getValue(); 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); 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.closedOnDate = new LocalDate().toDate();
this.withdrawnOnDate = null; this.withdrawnOnDate = null;
@@ -520,6 +544,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
preClosureInterestRate, interestCompoundedEvery, this.product.getInterestCompoundedEveryPeriodType()); preClosureInterestRate, interestCompoundedEvery, this.product.getInterestCompoundedEveryPeriodType());
this.total = accuredtotalAmount.getAmount(); this.total = accuredtotalAmount.getAmount();
this.interestAccrued = accuredtotalAmount.minus(deposit).getAmount();
} }
} }
@@ -4,7 +4,7 @@ public enum DepositAccountStatus {
INVALID(0, "depositStatusType.invalid"), // INVALID(0, "depositStatusType.invalid"), //
SUBMITED_AND_PENDING_APPROVAL(100, "depositStatusType.submitted.and.pending.approval"), // SUBMITED_AND_PENDING_APPROVAL(100, "depositStatusType.submitted.and.pending.approval"), //
APPROVED(200, "depositStatusType.approved"), // //APPROVED(200, "depositStatusType.approved"), //
ACTIVE(300, "depositStatusType.active"), // ACTIVE(300, "depositStatusType.active"), //
WITHDRAWN_BY_CLIENT(400, "depositStatusType.withdrawn.by.client"), // WITHDRAWN_BY_CLIENT(400, "depositStatusType.withdrawn.by.client"), //
REJECTED(500, "depositStatusType.rejected"), // REJECTED(500, "depositStatusType.rejected"), //
@@ -36,9 +36,9 @@ public enum DepositAccountStatus {
return this.value.equals(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL.getValue()); return this.value.equals(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL.getValue());
} }
public boolean isApproved() { /*public boolean isApproved() {
return this.value.equals(DepositAccountStatus.APPROVED.getValue()); return this.value.equals(DepositAccountStatus.APPROVED.getValue());
} }*/
public boolean isActive() { public boolean isActive() {
return this.value.equals(DepositAccountStatus.ACTIVE.getValue()); return this.value.equals(DepositAccountStatus.ACTIVE.getValue());
@@ -67,9 +67,9 @@ public enum DepositAccountStatus {
case 100: case 100:
enumeration = DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL; enumeration = DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL;
break; break;
case 200: /*case 200:
enumeration = DepositAccountStatus.APPROVED; enumeration = DepositAccountStatus.APPROVED;
break; break;*/
case 300: case 300:
enumeration = DepositAccountStatus.ACTIVE; enumeration = DepositAccountStatus.ACTIVE;
break; break;
@@ -45,17 +45,27 @@ public class DepositAccountTransaction extends AbstractPersistable<Long> {
@Column(name = "amount", scale = 6, precision = 19, nullable = false) @Column(name = "amount", scale = 6, precision = 19, nullable = false)
private final BigDecimal amount; 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(){ protected DepositAccountTransaction(){
this.depositAccount=null; this.depositAccount=null;
this.typeOf=null; this.typeOf=null;
this.amount=null; this.amount=null;
this.dateOf=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.typeOf = type;
this.amount = amount; this.amount = amount;
this.dateOf = date.toDateMidnight().toDate(); this.dateOf = date.toDateMidnight().toDate();
this.interest = interest;
this.total = amount.add(interest);
} }
public Date getDateOf() { public Date getDateOf() {
@@ -82,12 +92,12 @@ public class DepositAccountTransaction extends AbstractPersistable<Long> {
return DepositAccountTransactionType.DEPOSIT.equals(typeOf); return DepositAccountTransactionType.DEPOSIT.equals(typeOf);
} }
public static DepositAccountTransaction deposit(Money amount, LocalDate paymentDate) { public static DepositAccountTransaction deposit(Money amount, LocalDate paymentDate, Money interest) {
return new DepositAccountTransaction(DepositAccountTransactionType.DEPOSIT, amount.getAmount(), paymentDate); return new DepositAccountTransaction(DepositAccountTransactionType.DEPOSIT, amount.getAmount(), paymentDate, interest.getAmount());
} }
public static DepositAccountTransaction withdraw(Money amount, LocalDate paymentDate) { public static DepositAccountTransaction withdraw(Money amount, LocalDate paymentDate, Money interest) {
return new DepositAccountTransaction(DepositAccountTransactionType.WITHDRAW, amount.getAmount(), paymentDate); return new DepositAccountTransaction(DepositAccountTransactionType.WITHDRAW, amount.getAmount(), paymentDate, interest.getAmount());
} }
public void updateAccount(DepositAccount depositAccount) { public void updateAccount(DepositAccount depositAccount) {
@@ -35,7 +35,7 @@ public class DepositLifecycleStateMachineImpl implements
break; break;
case DEPOSIT_APPROVED: case DEPOSIT_APPROVED:
if (from.hasStateOf(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL)) { if (from.hasStateOf(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL)) {
newState = stateOf(DepositAccountStatus.APPROVED, allowedDepositStatuses); newState = stateOf(DepositAccountStatus.ACTIVE, allowedDepositStatuses);
} }
else{ else{
final String errorMessage = "The DepositApplication can not be approved from "+from.getCode() ; final String errorMessage = "The DepositApplication can not be approved from "+from.getCode() ;
@@ -43,7 +43,7 @@ public class DepositLifecycleStateMachineImpl implements
} }
break; break;
case DEPOSIT_WITHDRAWN: 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); newState = stateOf(DepositAccountStatus.WITHDRAWN_BY_CLIENT, allowedDepositStatuses);
} }
else{ else{
@@ -52,7 +52,7 @@ public class DepositLifecycleStateMachineImpl implements
} }
break; break;
case DEPOSIT_APPROVAL_UNDO: case DEPOSIT_APPROVAL_UNDO:
if (from.hasStateOf(DepositAccountStatus.APPROVED)) { if (from.hasStateOf(DepositAccountStatus.ACTIVE)) {
newState = stateOf(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL, allowedDepositStatuses); newState = stateOf(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL, allowedDepositStatuses);
} }
else{ else{
@@ -61,7 +61,7 @@ public class DepositLifecycleStateMachineImpl implements
} }
break; break;
case DEPOSIT_MATURED: case DEPOSIT_MATURED:
if (from.hasStateOf(DepositAccountStatus.APPROVED) ){ if (from.hasStateOf(DepositAccountStatus.ACTIVE) ){
newState = stateOf(DepositAccountStatus.MATURED, allowedDepositStatuses); newState = stateOf(DepositAccountStatus.MATURED, allowedDepositStatuses);
} }
else{ else{
@@ -79,7 +79,7 @@ public class DepositLifecycleStateMachineImpl implements
} }
break; break;
case DEPOSIT_PRECLOSED: case DEPOSIT_PRECLOSED:
if (from.hasStateOf(DepositAccountStatus.APPROVED) ){ if (from.hasStateOf(DepositAccountStatus.ACTIVE) ){
newState = stateOf(DepositAccountStatus.PRECLOSED, allowedDepositStatuses); newState = stateOf(DepositAccountStatus.PRECLOSED, allowedDepositStatuses);
} }
else{ else{
@@ -15,9 +15,9 @@ public class DepositAccountEnumerations {
case SUBMITED_AND_PENDING_APPROVAL: 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"); optionData = new EnumOptionData(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL.getValue().longValue(), DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL.getCode(), "Submitted and pending approval");
break; break;
case APPROVED: /*case APPROVED:
optionData = new EnumOptionData(DepositAccountStatus.APPROVED.getValue().longValue(), DepositAccountStatus.APPROVED.getCode(), "Approved"); optionData = new EnumOptionData(DepositAccountStatus.APPROVED.getValue().longValue(), DepositAccountStatus.APPROVED.getCode(), "Approved");
break; break;*/
case ACTIVE: case ACTIVE:
optionData = new EnumOptionData(DepositAccountStatus.ACTIVE.getValue().longValue(), DepositAccountStatus.ACTIVE.getCode(), "Active"); optionData = new EnumOptionData(DepositAccountStatus.ACTIVE.getValue().longValue(), DepositAccountStatus.ACTIVE.getCode(), "Active");
break; break;
@@ -247,11 +247,11 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
@Override @Override
public DepositPermissionData retrieveDepositAccountsPermissions(DepositAccountData depositAccountData) { public DepositPermissionData retrieveDepositAccountsPermissions(DepositAccountData depositAccountData) {
boolean pendingApproval = (depositAccountData.getStatus().getId().equals(100L)); boolean pendingApproval = (depositAccountData.getStatus().getId().equals(100L));
boolean undoApprovalAllowed = (depositAccountData.getStatus().getId().equals(200L)); boolean undoApprovalAllowed = (depositAccountData.getStatus().getId().equals(300L));
boolean isActive = (depositAccountData.getStatus().getId().equals(300L)); //boolean isActive = (depositAccountData.getStatus().getId().equals(300L));
boolean rejectAllowed = pendingApproval; boolean rejectAllowed = pendingApproval;
boolean withdrawnByApplicantAllowed = pendingApproval; boolean withdrawnByApplicantAllowed = pendingApproval;
return new DepositPermissionData(rejectAllowed, withdrawnByApplicantAllowed, undoApprovalAllowed, pendingApproval,isActive); return new DepositPermissionData(rejectAllowed, withdrawnByApplicantAllowed, undoApprovalAllowed, pendingApproval);
} }
} }
@@ -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<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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);
}
}
}
@@ -1,6 +1,7 @@
package org.mifosng.platform.saving.service; package org.mifosng.platform.saving.service;
import org.mifosng.platform.api.commands.DepositAccountCommand; 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.DepositAccountWithdrawalCommand;
import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand;
import org.mifosng.platform.api.commands.DepositStateTransitionCommand; 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')") @PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_APPROVE_DEPOSIT_ROLE', 'CAN_APPROVE_DEPOSIT_IN_THE_PAST_ROLE')")
EntityIdentifier undoDepositApproval(UndoStateTransitionCommand undoCommand); EntityIdentifier undoDepositApproval(UndoStateTransitionCommand undoCommand);
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_APPROVE_DEPOSIT_ROLE', 'CAN_APPROVE_DEPOSIT_IN_THE_PAST_ROLE')") /*@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_APPROVE_DEPOSIT_ROLE', 'CAN_APPROVE_DEPOSIT_IN_THE_PAST_ROLE')")
EntityIdentifier matureDepositApplication(DepositStateTransitionCommand command); EntityIdentifier matureDepositApplication(DepositStateTransitionCommand command);*/
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_APPROVE_DEPOSIT_ROLE', 'CAN_APPROVE_DEPOSIT_IN_THE_PAST_ROLE')") @PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_APPROVE_DEPOSIT_ROLE', 'CAN_APPROVE_DEPOSIT_IN_THE_PAST_ROLE')")
EntityIdentifier withdrawDepositAccountMoney(DepositAccountWithdrawalCommand command); 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);
} }
@@ -6,7 +6,9 @@ import java.util.List;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.Months;
import org.mifosng.platform.api.commands.DepositAccountCommand; 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.DepositAccountWithdrawalCommand;
import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand;
import org.mifosng.platform.api.commands.DepositStateTransitionCommand; import org.mifosng.platform.api.commands.DepositStateTransitionCommand;
@@ -238,7 +240,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
return new EntityIdentifier(account.getId()); return new EntityIdentifier(account.getId());
} }
@Transactional /*@Transactional
@Override @Override
public EntityIdentifier matureDepositApplication(DepositStateTransitionCommand command) { public EntityIdentifier matureDepositApplication(DepositStateTransitionCommand command) {
@@ -260,11 +262,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
account.matureDepositApplication(eventDate, defaultDepositLifecycleStateMachine()); account.matureDepositApplication(eventDate, defaultDepositLifecycleStateMachine());
this.depositAccountRepository.save(account); this.depositAccountRepository.save(account);
/*if(account.isRenewalAllowed()){ if(account.isRenewalAllowed()){
final DepositAccount renewedAccount = this.depositAccountAssembler.assembleFrom(account); final DepositAccount renewedAccount = this.depositAccountAssembler.assembleFrom(account);
this.depositAccountRepository.save(renewedAccount); this.depositAccountRepository.save(renewedAccount);
return new EntityIdentifier(renewedAccount.getId()); //returns the new deposit application id return new EntityIdentifier(renewedAccount.getId()); //returns the new deposit application id
}*/ }
String noteText = command.getNote(); String noteText = command.getNote();
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
@@ -273,7 +275,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
} }
return new EntityIdentifier(account.getId()); return new EntityIdentifier(account.getId());
} }*/
@Transactional @Transactional
@Override @Override
@@ -281,6 +283,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
context.authenticatedUser(); context.authenticatedUser();
DepositAccountWithdrawalCommandValidator validator = new DepositAccountWithdrawalCommandValidator(command);
validator.validate();
DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId());
if (account == null || account.isDeleted()) { if (account == null || account.isDeleted()) {
throw new DepositAccountNotFoundException(command.getAccountId()); throw new DepositAccountNotFoundException(command.getAccountId());
@@ -312,4 +317,41 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
} }
return new EntityIdentifier(account.getId()); 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());
}
} }
@@ -25,7 +25,7 @@ public class DepositStateTransitionApprovalCommandValidator {
baseDataValidator.reset().parameter("accountId").value(command.getAccountId()).notNull().integerGreaterThanZero(); baseDataValidator.reset().parameter("accountId").value(command.getAccountId()).notNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("commencementDate").value(command.getEventDate()).notNull(); 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("tenureInMonths").value(command.getTenureInMonths()).ignoreIfNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(command.getInterestCompoundedEveryPeriodType()).ignoreIfNull().inMinMaxRange(2, 2); baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(command.getInterestCompoundedEveryPeriodType()).ignoreIfNull().inMinMaxRange(2, 2);
@@ -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<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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);
}
}
}