Withdraw for deposit account

This commit is contained in:
Madhukar
2012-09-17 23:14:03 +05:30
parent 3293183279
commit 82ebfea45f
10 changed files with 91 additions and 43 deletions
@@ -209,9 +209,6 @@ public class DepositAccountsApiResource {
} else if (is(commandParam, "withdrewbyclient")) { } else if (is(commandParam, "withdrewbyclient")) {
EntityIdentifier identifier = this.depositAccountWritePlatformService.withdrawDepositApplication(command); EntityIdentifier identifier = this.depositAccountWritePlatformService.withdrawDepositApplication(command);
response = Response.ok().entity(identifier).build(); response = Response.ok().entity(identifier).build();
/*} else if (is(commandParam, "withdrawal")){
EntityIdentifier identifier = this.depositAccountWritePlatformService.matureDepositApplication(command);
response = Response.ok().entity(identifier).build();*/
} }
UndoStateTransitionCommand undoCommand = new UndoStateTransitionCommand(accountId, command.getNote()); UndoStateTransitionCommand undoCommand = new UndoStateTransitionCommand(accountId, command.getNote());
@@ -1156,7 +1156,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType(); Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap); Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(Arrays.asList("renewAccount","deposit", "note")); Set<String> supportedParams = new HashSet<String>(Arrays.asList("renewAccount","deposit", "note","locale"));
checkForUnsupportedParameters(requestMap, supportedParams); checkForUnsupportedParameters(requestMap, supportedParams);
@@ -0,0 +1,11 @@
package org.mifosng.platform.exceptions;
import org.joda.time.LocalDate;
public class DepositAccountReopenException extends AbstractPlatformResourceNotFoundException{
public DepositAccountReopenException(LocalDate maturedDate) {
super("error.msg.depositaccount.cannot.reopen.before.mature", "You cannot renew the account that is not matured:"+maturedDate);
}
}
@@ -23,6 +23,7 @@ import org.apache.commons.lang.StringUtils;
import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption; import org.hibernate.annotations.LazyCollectionOption;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.Months;
import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand;
import org.mifosng.platform.client.domain.Client; import org.mifosng.platform.client.domain.Client;
import org.mifosng.platform.currency.domain.MonetaryCurrency; import org.mifosng.platform.currency.domain.MonetaryCurrency;
@@ -304,6 +305,10 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
return projectedTotalOnMaturity; return projectedTotalOnMaturity;
} }
public BigDecimal getTotal() {
return total;
}
public void reject(final LocalDate rejectedOn, public void reject(final LocalDate rejectedOn,
final DepositLifecycleStateMachine depositLifecycleStateMachine) { final DepositLifecycleStateMachine depositLifecycleStateMachine) {
@@ -474,46 +479,49 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
public void withdrawDepositAccountMoney(boolean renewAccount, DepositLifecycleStateMachine depositLifecycleStateMachine) { public void withdrawDepositAccountMoney(boolean renewAccount, DepositLifecycleStateMachine depositLifecycleStateMachine) {
if (new LocalDate().isAfter(maturesOnDate()) || new LocalDate().equals(maturesOnDate())) { if (new LocalDate().isAfter(maturesOnDate()) || new LocalDate().equals(maturesOnDate())) {
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(
DepositAccountEvent.DEPOSIT_MATURED, DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_MATURED, DepositAccountStatus.fromInt(this.depositStatus));
DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnum.getValue(); this.depositStatus = statusEnum.getValue();
if(!renewAccount){ DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(Money.of(this.currency, this.total), new LocalDate());
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(Money.of(this.currency, this.total), new LocalDate()); depositaccountTransaction.updateAccount(this);
depositaccountTransaction.updateAccount(this); this.depositaccountTransactions.add(depositaccountTransaction);
this.depositaccountTransactions.add(depositaccountTransaction);
DepositAccountStatus statusEnumForClose = depositLifecycleStateMachine.transition( DepositAccountStatus statusEnumForClose = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CLOSED, DepositAccountStatus.fromInt(this.depositStatus));
DepositAccountEvent.DEPOSIT_CLOSED, this.depositStatus = statusEnumForClose.getValue();
DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnumForClose.getValue();
this.depositAmount = null; this.closedOnDate = new LocalDate().toDate();
this.interestRate = null; this.withdrawnOnDate = null;
this.tenureInMonths = null; this.rejectedOnDate = null;
this.interestCompoundedEvery = null;
this.interestCompoundedFrequencyType = null;
this.closedOnDate = new LocalDate().toDate();
this.withdrawnOnDate = null;
this.rejectedOnDate = null;
}else if(renewAccount){ }else if(new LocalDate().isBefore(maturesOnDate())){
DepositAccountStatus statusEnumForClose = depositLifecycleStateMachine.transition(
DepositAccountEvent.DEPOSIT_CLOSED,
DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnumForClose.getValue();
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(Money.of(this.currency, this.total), new LocalDate()); DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_PRECLOSED, DepositAccountStatus.fromInt(this.depositStatus));
depositaccountTransaction.updateAccount(this); this.depositStatus = statusEnum.getValue();
this.depositaccountTransactions.add(depositaccountTransaction);
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(Money.of(this.currency, this.total), new LocalDate());
depositaccountTransaction.updateAccount(this);
this.depositaccountTransactions.add(depositaccountTransaction);
this.closedOnDate = new LocalDate().toDate();
this.withdrawnOnDate = null;
this.rejectedOnDate = null;
this.closedOnDate = new LocalDate().toDate();
this.withdrawnOnDate = null;
this.rejectedOnDate = null;
}
} }
}
public void adjustTotalAmountForPreclosureInterest(DepositAccount account, FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator) {
LocalDate commnencementDate = new LocalDate(this.actualCommencementDate);
LocalDate preClosedDate = new LocalDate();
Integer tenure = Months.monthsBetween(commnencementDate, preClosedDate).getMonths();
Money deposit = Money.of(account.getDeposit().getCurrency(), account.getDeposit().getAmount());
Money accuredtotalAmount = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit, tenure,
preClosureInterestRate, interestCompoundedEvery, this.product.getInterestCompoundedEveryPeriodType());
this.total = accuredtotalAmount.getAmount();
} }
} }
@@ -2,6 +2,6 @@ package org.mifosng.platform.saving.domain;
public enum DepositAccountEvent { public enum DepositAccountEvent {
DEPOSIT_CREATED, DEPOSIT_REJECTED, DEPOSIT_APPROVED, DEPOSIT_APPROVAL_UNDO, DEPOSIT_WITHDRAWN, DEPOSIT_MATURED, DEPOSIT_CLOSED; DEPOSIT_CREATED, DEPOSIT_REJECTED, DEPOSIT_APPROVED, DEPOSIT_APPROVAL_UNDO, DEPOSIT_WITHDRAWN, DEPOSIT_MATURED, DEPOSIT_CLOSED, DEPOSIT_PRECLOSED;
} }
@@ -9,7 +9,8 @@ public enum DepositAccountStatus {
WITHDRAWN_BY_CLIENT(400, "depositStatusType.withdrawn.by.client"), // WITHDRAWN_BY_CLIENT(400, "depositStatusType.withdrawn.by.client"), //
REJECTED(500, "depositStatusType.rejected"), // REJECTED(500, "depositStatusType.rejected"), //
CLOSED(600, "depositStatusType.closed"), // CLOSED(600, "depositStatusType.closed"), //
MATURED(700,"depositStatusType.matured"); MATURED(700,"depositStatusType.matured"),
PRECLOSED(800,"depositStatusType.preclosed");
private final Integer value; private final Integer value;
private final String code; private final String code;
@@ -55,6 +56,10 @@ public enum DepositAccountStatus {
return this.value.equals(DepositAccountStatus.REJECTED.getValue()); return this.value.equals(DepositAccountStatus.REJECTED.getValue());
} }
public boolean isPreClosed(){
return this.value.equals(DepositAccountStatus.PRECLOSED.getValue());
}
public static DepositAccountStatus fromInt(final Integer statusValue) { public static DepositAccountStatus fromInt(final Integer statusValue) {
DepositAccountStatus enumeration = DepositAccountStatus.INVALID; DepositAccountStatus enumeration = DepositAccountStatus.INVALID;
@@ -80,7 +85,10 @@ public enum DepositAccountStatus {
case 700: case 700:
enumeration = DepositAccountStatus.MATURED; enumeration = DepositAccountStatus.MATURED;
break; break;
} case 800:
enumeration = DepositAccountStatus.PRECLOSED;
break;
}
return enumeration; return enumeration;
} }
} }
@@ -78,8 +78,18 @@ public class DepositLifecycleStateMachineImpl implements
throw new InvalidDepositStateTransitionException("closed", "failed", errorMessage,from); throw new InvalidDepositStateTransitionException("closed", "failed", errorMessage,from);
} }
break; break;
case DEPOSIT_PRECLOSED:
if (from.hasStateOf(DepositAccountStatus.APPROVED) ){
newState = stateOf(DepositAccountStatus.PRECLOSED, allowedDepositStatuses);
}
else{
final String errorMessage = "The DepositApplication can not be matured from "+from.getCode() ;
throw new InvalidDepositStateTransitionException("preclosure", "failed", errorMessage,from);
}
break;
default: default:
break; break;
} }
return newState; return newState;
@@ -147,4 +147,8 @@ public class DepositAccountAssembler {
return newAccount; return newAccount;
} }
public void adjustTotalAmountForPreclosureInterest(DepositAccount account) {
account.adjustTotalAmountForPreclosureInterest(account,this.fixedTermDepositInterestCalculator);
}
} }
@@ -33,6 +33,9 @@ public class DepositAccountEnumerations {
case CLOSED: case CLOSED:
optionData = new EnumOptionData(DepositAccountStatus.CLOSED.getValue().longValue(), DepositAccountStatus.CLOSED.getCode(), "Closed"); optionData = new EnumOptionData(DepositAccountStatus.CLOSED.getValue().longValue(), DepositAccountStatus.CLOSED.getCode(), "Closed");
break; break;
case PRECLOSED:
optionData = new EnumOptionData(DepositAccountStatus.PRECLOSED.getValue().longValue(), DepositAccountStatus.PRECLOSED.getCode(), "Preclosed");
break;
default: default:
optionData = new EnumOptionData(DepositAccountStatus.INVALID.getValue().longValue(), DepositAccountStatus.INVALID.getCode(), "Invalid"); optionData = new EnumOptionData(DepositAccountStatus.INVALID.getValue().longValue(), DepositAccountStatus.INVALID.getCode(), "Invalid");
break; break;
@@ -15,6 +15,7 @@ import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.client.domain.Note; import org.mifosng.platform.client.domain.Note;
import org.mifosng.platform.client.domain.NoteRepository; import org.mifosng.platform.client.domain.NoteRepository;
import org.mifosng.platform.exceptions.DepositAccountNotFoundException; import org.mifosng.platform.exceptions.DepositAccountNotFoundException;
import org.mifosng.platform.exceptions.DepositAccountReopenException;
import org.mifosng.platform.exceptions.NoAuthorizationException; import org.mifosng.platform.exceptions.NoAuthorizationException;
import org.mifosng.platform.exceptions.PlatformDataIntegrityException; import org.mifosng.platform.exceptions.PlatformDataIntegrityException;
import org.mifosng.platform.exceptions.ProductNotFoundException; import org.mifosng.platform.exceptions.ProductNotFoundException;
@@ -285,14 +286,20 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
throw new DepositAccountNotFoundException(command.getAccountId()); throw new DepositAccountNotFoundException(command.getAccountId());
} }
if(new LocalDate().isBefore(account.maturesOnDate())){
this.depositAccountAssembler.adjustTotalAmountForPreclosureInterest(account);
}
account.withdrawDepositAccountMoney(command.isRenewAccount(), defaultDepositLifecycleStateMachine()); account.withdrawDepositAccountMoney(command.isRenewAccount(), defaultDepositLifecycleStateMachine());
this.depositAccountRepository.save(account); this.depositAccountRepository.save(account);
BigDecimal deposit = account.getProjectedTotalOnMaturity();
if(command.getDeposit() != null)
deposit = command.getDeposit();
if(command.isRenewAccount()){ if(command.isRenewAccount()){
BigDecimal deposit = account.getTotal();
if(command.getDeposit() != null)
deposit = command.getDeposit();
if(new LocalDate().isBefore(account.maturesOnDate())){
throw new DepositAccountReopenException(account.maturesOnDate());
}
final DepositAccount renewedAccount = this.depositAccountAssembler.assembleFrom(account,deposit); final DepositAccount renewedAccount = this.depositAccountAssembler.assembleFrom(account,deposit);
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