withdraw_renew_of deposit application on maturity

This commit is contained in:
Madhukar
2012-09-13 15:36:26 +01:00
committed by Keith Woodlock
parent bacb5bfe64
commit 45200343be
6 changed files with 117 additions and 9 deletions
@@ -205,7 +205,7 @@ 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, "matureAccount")){ } else if (is(commandParam, "mature")){
EntityIdentifier identifier = this.depositAccountWritePlatformService.matureDepositApplication(command); EntityIdentifier identifier = this.depositAccountWritePlatformService.matureDepositApplication(command);
response = Response.ok().entity(identifier).build(); response = Response.ok().entity(identifier).build();
} }
@@ -12,6 +12,7 @@ import javax.persistence.Entity;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy; import javax.persistence.OrderBy;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.Temporal; import javax.persistence.Temporal;
@@ -136,6 +137,10 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "depositAccount", orphanRemoval = true) @OneToMany(cascade = CascadeType.ALL, mappedBy = "depositAccount", orphanRemoval = true)
private final List<DepositAccountTransaction> depositaccountTransactions = new ArrayList<DepositAccountTransaction>(); private final List<DepositAccountTransaction> depositaccountTransactions = new ArrayList<DepositAccountTransaction>();
@OneToOne(optional=true, cascade={CascadeType.PERSIST})
@JoinColumn(name = "renewed_account_id")
private DepositAccount renewdAccount;
public DepositAccount openNew( public DepositAccount openNew(
final Client client, final DepositProduct product, final Client client, final DepositProduct product,
final String externalId, final Money deposit, final BigDecimal maturityInterestRate, final BigDecimal preClosureInterestRate, final Integer tenureInMonths, final String externalId, final Money deposit, final BigDecimal maturityInterestRate, final BigDecimal preClosureInterestRate, final Integer tenureInMonths,
@@ -382,9 +387,21 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
return this.client; return this.client;
} }
public DepositProduct product(){
return this.product;
}
public String getExternalId() {
return this.externalId;
}
public boolean isRenewalAllowed() {
return renewalAllowed;
}
public void matureDepositApplication(LocalDate maturedOnDate, DepositLifecycleStateMachine depositLifecycleStateMachine) { public void matureDepositApplication(LocalDate maturedOnDate, DepositLifecycleStateMachine depositLifecycleStateMachine) {
if (maturedOnDate.isAfter(maturesOnDate()) || new LocalDate().equals(maturesOnDate())) { if (maturedOnDate.isAfter(maturesOnDate()) || (new LocalDate().equals(maturesOnDate()) && maturedOnDate.equals(maturesOnDate()))) {
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition( DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(
DepositAccountEvent.DEPOSIT_MATURED, DepositAccountEvent.DEPOSIT_MATURED,
DepositAccountStatus.fromInt(this.depositStatus)); DepositAccountStatus.fromInt(this.depositStatus));
@@ -394,19 +411,49 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(Money.of(this.currency, this.total), maturedOnDate); DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(Money.of(this.currency, this.total), maturedOnDate);
depositaccountTransaction.updateAccount(this); depositaccountTransaction.updateAccount(this);
this.depositaccountTransactions.add(depositaccountTransaction); this.depositaccountTransactions.add(depositaccountTransaction);
DepositAccountStatus statusEnumForClose = depositLifecycleStateMachine.transition(
DepositAccountEvent.DEPOSIT_CLOSED,
DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnumForClose.getValue();
this.depositAmount = null;
this.interestRate = null;
this.tenureInMonths = null;
this.interestCompoundedEvery = null;
this.interestCompoundedFrequencyType = null;
this.closedOnDate = maturedOnDate.toDate();
this.withdrawnOnDate = null;
this.rejectedOnDate = null;
}else if(this.renewalAllowed){
DepositAccountStatus statusEnumForClose = depositLifecycleStateMachine.transition(
DepositAccountEvent.DEPOSIT_CLOSED,
DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnumForClose.getValue();
this.closedOnDate = maturedOnDate.toDate();
this.withdrawnOnDate = null;
this.rejectedOnDate = null;
} }
} }
if (maturedOnDate.isBefore(new LocalDate()) || maturedOnDate.isBefore(maturesOnDate())) {
if (maturesOnDate().isBefore(new LocalDate())) { final String errorMessage = "The date on which a deposit matured is cannot be before its matured date: "
final String errorMessage = "The date on which a deposit is rejected cannot be before its submittal date: "
+ new LocalDate().toString(); + new LocalDate().toString();
throw new InvalidDepositStateTransitionException("reject", throw new InvalidDepositStateTransitionException("matured",
"cannot.be.before.submittal.date", errorMessage, "cannot.be.before.mature.date", errorMessage,
maturedOnDate, new LocalDate()); maturedOnDate, new LocalDate());
} }
if(maturedOnDate.equals(maturesOnDate())&& !(maturesOnDate().equals(new LocalDate()))){
final String errorMessage = "You can not manually mature the deposit account till the maturity date reached "
+ new LocalDate().toString();
throw new InvalidDepositStateTransitionException("matured",
"cannot.manual.mature.deposit.account.date", errorMessage,
maturedOnDate, new LocalDate());
}
} }
public LocalDate maturesOnDate() { public LocalDate maturesOnDate() {
@@ -416,4 +463,10 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
} }
return date; return date;
} }
public void updateAccount(DepositAccount account) {
this.renewdAccount = account;
}
} }
@@ -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_CREATED, DEPOSIT_REJECTED, DEPOSIT_APPROVED, DEPOSIT_APPROVAL_UNDO, DEPOSIT_WITHDRAWN, DEPOSIT_MATURED, DEPOSIT_CLOSED;
} }
@@ -69,6 +69,17 @@ public class DepositLifecycleStateMachineImpl implements
throw new InvalidDepositStateTransitionException("mature", "failed", errorMessage,from); throw new InvalidDepositStateTransitionException("mature", "failed", errorMessage,from);
} }
break; break;
case DEPOSIT_CLOSED:
if (from.hasStateOf(DepositAccountStatus.MATURED) ){
newState = stateOf(DepositAccountStatus.CLOSED, allowedDepositStatuses);
}
else{
final String errorMessage = "The DepositApplication can not be closed from "+from.getCode() ;
throw new InvalidDepositStateTransitionException("closed", "failed", errorMessage,from);
}
break;
default:
break;
} }
return newState; return newState;
@@ -109,4 +109,42 @@ public class DepositAccountAssembler {
List<DepositAccountStatus> allowedDepositStatuses = Arrays.asList(DepositAccountStatus.values()); List<DepositAccountStatus> allowedDepositStatuses = Arrays.asList(DepositAccountStatus.values());
return new DepositLifecycleStateMachineImpl(allowedDepositStatuses); return new DepositLifecycleStateMachineImpl(allowedDepositStatuses);
} }
public DepositAccount assembleFrom(DepositAccount account) {
Client client = account.client();
DepositProduct product = account.product();
Money deposit = Money.of(product.getCurrency(), account.getDeposit().getAmount());
Integer tenureInMonths = product.getTenureInMonths();
BigDecimal maturityInterestRate = product.getMaturityDefaultInterestRate();
BigDecimal preClosureInterestRate = product.getPreClosureInterestRate();
if(product.getMaturityMinInterestRate().compareTo(preClosureInterestRate)==-1){
throw new DepositAccounDataValidationtException(preClosureInterestRate, product.getMaturityMinInterestRate());
}
Integer compoundingInterestEvery = product.getInterestCompoundedEvery();
PeriodFrequencyType compoundingInterestFrequency = product.getInterestCompoundedEveryPeriodType();
boolean renewalAllowed = product.isRenewalAllowed();
boolean preClosureAllowed = product.isPreClosureAllowed();
DepositAccount newAccount =new DepositAccount().openNew(client, product, null,
deposit,
maturityInterestRate, preClosureInterestRate,
tenureInMonths, compoundingInterestEvery, compoundingInterestFrequency,
account.maturesOnDate(),
renewalAllowed, preClosureAllowed, this.fixedTermDepositInterestCalculator, defaultDepositLifecycleStateMachine());
newAccount.updateAccount(account);
return newAccount;
}
} }
@@ -257,6 +257,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
account.matureDepositApplication(eventDate, defaultDepositLifecycleStateMachine()); account.matureDepositApplication(eventDate, defaultDepositLifecycleStateMachine());
this.depositAccountRepository.save(account); this.depositAccountRepository.save(account);
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(); String noteText = command.getNote();
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
Note note = Note.depositNote(account, noteText); Note note = Note.depositNote(account, noteText);