Add edit option for deposit account

This commit is contained in:
Madhukar
2013-04-17 20:55:47 +05:30
parent f3c63671a0
commit fd20f72814
14 changed files with 256 additions and 17 deletions
@@ -10,6 +10,7 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -87,6 +88,19 @@ public class DepositAccountsApiResource {
return Response.ok().entity(entityIdentifier).build();
}
@PUT
@Path("{accountId}")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response updateDepositAccount(@PathParam("accountId") final Long accountId,final String jsonRequestBody){
final DepositAccountCommand command = this.apiDataConversionService.convertJsonToDepositAccountCommand(accountId, jsonRequestBody);
EntityIdentifier entityIdentifier = this.depositAccountWritePlatformService.updateDepositAccount(command);
return Response.ok().entity(entityIdentifier).build();
}
@GET
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
@@ -123,19 +123,35 @@ public class DepositAccountCommand {
public boolean isNoFieldChanged() {
return this.modifiedParameters.isEmpty();
}
public boolean isExternalIdChanged(){
return this.modifiedParameters.contains("externalId");
}
public boolean isDepositAmountChanged(){
return this.modifiedParameters.contains("deposit");
}
public boolean isTenureInMonthsChanged() {
return this.modifiedParameters.contains("tenureInMonths");
}
public boolean isMaturityActualInterestRateChanged() {
return this.modifiedParameters.contains("interestRate");
return this.modifiedParameters.contains("maturityInterestRate");
}
public boolean isPreClosureInterestRateChanged(){
return this.modifiedParameters.contains("preClosureInterestRate");
}
public boolean isCompoundingInterestEveryChanged(){
return this.modifiedParameters.contains("interestCompoundedEvery");
}
public boolean isInterestCompoundedEveryPeriodTypeChaged(){
return this.modifiedParameters.contains("interestCompoundedEveryPeriodType");
}
public boolean isRenewalAllowedChanged() {
return this.modifiedParameters.contains("renewalAllowed");
}
@@ -151,4 +167,8 @@ public class DepositAccountCommand {
public boolean isInterestCompoundingAllowedChanged(){
return this.modifiedParameters.contains("interestCompoundingAllowed");
}
public boolean isCommencementDateChanged() {
return this.modifiedParameters.contains("commencementDate");
}
}
@@ -1,14 +1,18 @@
package org.mifosng.platform.api.commands;
import org.joda.time.LocalDate;
public class DepositAccountWithdrawalCommand {
private final Long accountId;
private final String note;
private final LocalDate maturesOnDate;
public DepositAccountWithdrawalCommand(final Long accountId, final String note) {
public DepositAccountWithdrawalCommand(final Long accountId, final String note, final LocalDate maturesOnDate) {
this.accountId = accountId;
this.note = note;
this.maturesOnDate=maturesOnDate;
}
public Long getAccountId() {
@@ -18,4 +22,8 @@ public class DepositAccountWithdrawalCommand {
public String getNote() {
return note;
}
public LocalDate getMaturesOnDate() {
return maturesOnDate;
}
}
@@ -10,17 +10,20 @@ public class DepositStateTransitionApprovalCommand {
private final Long productId;
private final LocalDate eventDate;
private final BigDecimal depositAmount;
private final BigDecimal maturityInterestRate;
private final Integer tenureInMonths;
private final Integer interestCompoundedEveryPeriodType;
private final Integer interestCompoundedEvery;
private final String note;
public DepositStateTransitionApprovalCommand(Long resourceIdentifier, Long productId, LocalDate eventDate, Integer tenureInMonths, BigDecimal depositAmount, Integer interestCompoundedEveryPeriodType, Integer interestCompoundedEvery, String note) {
public DepositStateTransitionApprovalCommand(final Long resourceIdentifier,final Long productId,final LocalDate eventDate,final Integer tenureInMonths,
final BigDecimal depositAmount,final Integer interestCompoundedEveryPeriodType,final Integer interestCompoundedEvery,final String note,final BigDecimal maturityInterestRate) {
this.accountId=resourceIdentifier;
this.eventDate=eventDate;
this.depositAmount=depositAmount;
this.maturityInterestRate=maturityInterestRate;
this.tenureInMonths=tenureInMonths;
this.interestCompoundedEveryPeriodType=interestCompoundedEveryPeriodType;
this.productId=productId;
@@ -42,6 +45,10 @@ public class DepositStateTransitionApprovalCommand {
return depositAmount;
}
public BigDecimal getMaturityInterestRate() {
return maturityInterestRate;
}
public Integer getTenureInMonths() {
return tenureInMonths;
}
@@ -259,8 +259,8 @@ public class DepositAccountData {
this.interestPaid =interestPaid;
this.isInterestWithdrawable=isInterestWithdrawable;
this.interestCompoundingAllowed = interestCompoundingAllowed;
this.availableInterestForWithdrawal = new BigDecimal(0);
this.availableWithdrawalAmount = new BigDecimal(0);
this.availableInterestForWithdrawal = BigDecimal.ZERO;
this.availableWithdrawalAmount = BigDecimal.ZERO;
}
public DepositAccountData(
@@ -313,8 +313,8 @@ public class DepositAccountData {
this.interestPaid=null;
this.isInterestWithdrawable=false;
this.interestCompoundingAllowed=interestCompoundingAllowed;
this.availableInterestForWithdrawal= new BigDecimal(0);
this.availableWithdrawalAmount = new BigDecimal(0);
this.availableInterestForWithdrawal= BigDecimal.ZERO;
this.availableWithdrawalAmount = BigDecimal.ZERO;
}
public Long getId() {
@@ -98,10 +98,10 @@ public class DepositProductData {
this.currencyCode=null;
this.digitsAfterDecimal=Integer.valueOf(0);
this.minimumBalance=BigDecimal.ZERO;
this.maximumBalance=null;
this.maximumBalance=BigDecimal.ZERO;
this.tenureInMonths=Integer.valueOf(0);
this.maturityDefaultInterestRate = null;
this.maturityDefaultInterestRate = BigDecimal.ZERO;
this.maturityMinInterestRate=BigDecimal.ZERO;
this.maturityMaxInterestRate=BigDecimal.ZERO;
this.interestCompoundedEvery = Integer.valueOf(1);
@@ -1371,7 +1371,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(Arrays.asList("locale","commencementDate", "locale", "dateFormat", "tenureInMonths", "deposit", "interestCompoundedEveryPeriodType", "productId","interestCompoundedEvery","note"));
Set<String> supportedParams = new HashSet<String>(Arrays.asList("locale","commencementDate", "locale", "dateFormat", "tenureInMonths", "deposit", "interestCompoundedEveryPeriodType", "productId","interestCompoundedEvery","note","maturityInterestRate"));
checkForUnsupportedParameters(requestMap, supportedParams);
@@ -1379,13 +1379,14 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
LocalDate commencementDate = extractLocalDateParameter("commencementDate", requestMap, modifiedParameters);
BigDecimal deposit=extractBigDecimalParameter("deposit", requestMap, modifiedParameters);
BigDecimal maturityInterestRate=extractBigDecimalParameter("maturityInterestRate", requestMap, modifiedParameters);
Integer tenureInMonths = extractIntegerParameter("tenureInMonths", requestMap, modifiedParameters);
Integer interestCompoundedEveryPeriodType = extractIntegerParameter("interestCompoundedEveryPeriodType", requestMap, modifiedParameters);
Integer interestCompoundedEvery = extractIntegerParameter("interestCompoundedEvery", requestMap, modifiedParameters);
Long productId = extractLongParameter("productId", requestMap, modifiedParameters);
String note = extractStringParameter("note", requestMap, modifiedParameters);
return new DepositStateTransitionApprovalCommand(resourceIdentifier, productId, commencementDate, tenureInMonths, deposit, interestCompoundedEveryPeriodType,interestCompoundedEvery, note);
return new DepositStateTransitionApprovalCommand(resourceIdentifier, productId, commencementDate, tenureInMonths, deposit, interestCompoundedEveryPeriodType,interestCompoundedEvery, note,maturityInterestRate);
}
@Override
@@ -1398,15 +1399,16 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(Arrays.asList("note","locale"));
Set<String> supportedParams = new HashSet<String>(Arrays.asList("note","locale","maturesOnDate", "dateFormat"));
checkForUnsupportedParameters(requestMap, supportedParams);
Set<String> modifiedParameters = new HashSet<String>();
String note = extractStringParameter("note", requestMap, modifiedParameters);
LocalDate maturesOnDate = extractLocalDateParameter("maturesOnDate", requestMap, modifiedParameters);
return new DepositAccountWithdrawalCommand(resourceIdentifier,note);
return new DepositAccountWithdrawalCommand(resourceIdentifier,note,maturesOnDate);
}
@Override
@@ -44,7 +44,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne
@JoinColumn(name = "product_id")
private final DepositProduct product;
private DepositProduct product;
@Column(name = "external_id")
private String externalId;
@@ -266,9 +266,15 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
this.tenureInMonths = command.getTenureInMonths();
}
if(command.getMaturityInterestRate() != null){
this.interestRate = command.getMaturityInterestRate();
}
this.product.validateInterestRateInRange(this.interestRate);
if (command.getDepositAmount() != null) {
this.depositAmount = command.getDepositAmount();
}
this.product.validateDepositInRange(this.depositAmount);
if (command.getInterestCompoundedEveryPeriodType() != null) {
this.interestCompoundedFrequencyType = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()).getValue();
@@ -418,6 +424,8 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
this.depositStatus = statusEnum.getValue();
this.actualCommencementDate = null;
this.projectedInterestAccruedOnMaturity=this.interestAccrued;
this.projectedTotalOnMaturity = this.depositAmount.add(this.projectedInterestAccruedOnMaturity);
this.maturesOnDate = getProjectedCommencementDate().plusMonths(this.tenureInMonths).toDate();
this.total=null;
this.interestAccrued=null;
@@ -580,4 +588,54 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
this.closedOnDate = new LocalDate().toDate();
}
public void update(final DepositProduct product, final String externalId,
final LocalDate commencementDate, final Money deposit,
final Integer tenureInMonths, final BigDecimal maturityInterestRate,
final BigDecimal preClosureInterestRate, final Integer interestCompoundedEvery,
final PeriodFrequencyType compoundingInterestFrequency,
final boolean renewalAllowed, final boolean preClosureAllowed,
final boolean isInterestWithdrawable, final boolean isInterestCompoundingAllowed,
final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator,
final DepositLifecycleStateMachine depositLifecycleStateMachine) {
Money futureValueOnMaturity =null;
if (isInterestCompoundingAllowed) {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit, tenureInMonths,
maturityInterestRate, interestCompoundedEvery,
compoundingInterestFrequency);
} else {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityForSimpleInterest(deposit,
tenureInMonths, maturityInterestRate,
interestCompoundedEvery,
compoundingInterestFrequency);
}
setExternalId(externalId);
if (commencementDate != null) {
this.projectedCommencementDate = commencementDate.toDate();
this.maturesOnDate = commencementDate.plusMonths(this.tenureInMonths).toDate();
}
this.product = product;
this.depositAmount = deposit.getAmount();
this.tenureInMonths = tenureInMonths;
this.interestRate = maturityInterestRate;
this.product.validateInterestRateInRange(maturityInterestRate);
this.preClosureInterestRate=preClosureInterestRate;
this.interestCompoundedEvery=interestCompoundedEvery;
this.interestCompoundedFrequencyType=compoundingInterestFrequency.getValue();
this.renewalAllowed=renewalAllowed;
this.preClosureAllowed=preClosureAllowed;
this.isInterestWithdrawable=isInterestWithdrawable;
this.interestCompoundingAllowed=isInterestCompoundingAllowed;
this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.minus(deposit).getAmount();
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
}
public void update(final boolean renewalAllowed, final boolean isInterestWithdrawable) {
this.renewalAllowed=renewalAllowed;
this.isInterestWithdrawable=isInterestWithdrawable;
}
}
@@ -4,6 +4,7 @@ import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosng.platform.api.commands.DepositAccountCommand;
import org.mifosng.platform.client.domain.Client;
import org.mifosng.platform.client.domain.ClientRepository;
@@ -201,4 +202,96 @@ public class DepositAccountAssembler {
public void adjustTotalAmountForPreclosureInterest(DepositAccount account) {
account.adjustTotalAmountForPreclosureInterest(account,this.fixedTermDepositInterestCalculator);
}
public void assembleUpdatedDepositAccount(DepositAccount account,DepositAccountCommand command) {
DepositProduct product = account.product();
if(command.getProductId() != null){
product = this.depositProductRepository.findOne(command.getProductId());
if (product == null || product.isDeleted()) {
throw new DepositProductNotFoundException(command.getProductId());
}
}
String externalId = account.getExternalId();
if(command.isExternalIdChanged()){
externalId = command.getExternalId();
}
LocalDate commencementDate = account.getProjectedCommencementDate();
if(command.isCommencementDateChanged()){
commencementDate = new LocalDate(command.getCommencementDate());
}
Money deposit = account.getDeposit();
if(command.isDepositAmountChanged()){
deposit = Money.of(product.getCurrency(), command.getDepositAmount());
}
Integer tenureInMonths = account.getTenureInMonths();
if(command.isTenureInMonthsChanged()){
tenureInMonths =command.getTenureInMonths();
}
BigDecimal maturityInterestRate = account.getInterestRate();
if(command.isMaturityActualInterestRateChanged()){
maturityInterestRate = command.getMaturityInterestRate();
}
BigDecimal preClosureInterestRate = account.getPreClosureInterestRate();
if(command.isPreClosureInterestRateChanged()){
preClosureInterestRate = command.getPreClosureInterestRate();
}
if(product.getMaturityMinInterestRate().compareTo(preClosureInterestRate)==-1){
throw new DepositAccounDataValidationtException(preClosureInterestRate, product.getMaturityMinInterestRate());
}
Integer compoundingInterestEvery = account.getInterestCompoundedEvery();
if(command.isCompoundingInterestEveryChanged()){
compoundingInterestEvery = command.getInterestCompoundedEvery();
}
PeriodFrequencyType compoundingInterestFrequency = account.getInterestCompoundedFrequencyType();
if(command.getInterestCompoundedEveryPeriodType() !=null){
compoundingInterestFrequency = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType());
}
boolean renewalAllowed = account.isRenewalAllowed();
if(command.isRenewalAllowedChanged()){
renewalAllowed = command.isRenewalAllowed();
}
boolean preClosureAllowed = account.isPreClosureAllowed();
if(command.isPreClosureAllowedChanged()){
preClosureAllowed = command.isPreClosureAllowed();
}
boolean isInterestWithdrawable = account.isInterestWithdrawable();
if(command.isInterestWithdrawableChanged()){
isInterestWithdrawable = command.isInterestWithdrawable();
}
boolean isInterestCompoundingAllowed = account.isInterestCompoundingAllowed();
if(command.isInterestCompoundingAllowedChanged()){
isInterestCompoundingAllowed = command.isInterestCompoundingAllowed();
}
account.update(product,externalId,commencementDate,deposit,tenureInMonths,maturityInterestRate,preClosureInterestRate,compoundingInterestEvery,compoundingInterestFrequency,renewalAllowed,
preClosureAllowed,isInterestWithdrawable,isInterestCompoundingAllowed,this.fixedTermDepositInterestCalculator,defaultDepositLifecycleStateMachine());
}
public void updateApprovedDepositAccount(DepositAccount account, DepositAccountCommand command) {
boolean renewalAllowed = account.isRenewalAllowed();
if(command.isRenewalAllowedChanged()){
renewalAllowed = command.isRenewalAllowed();
}
boolean isInterestWithdrawable = account.isInterestWithdrawable();
if(command.isInterestWithdrawableChanged()){
isInterestWithdrawable = command.isInterestWithdrawable();
}
account.update(renewalAllowed,isInterestWithdrawable);
}
}
@@ -27,7 +27,7 @@ public class DepositAccountCommandValidator {
baseDataValidator.reset().parameter("productId").value(command.getProductId()).ignoreIfNull().notNull();
baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100);
baseDataValidator.reset().parameter("depositAmount").value(command.getDepositAmount()).ignoreIfNull().notNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("deposit").value(command.getDepositAmount()).ignoreIfNull().notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityInterestRate").value(command.getMaturityInterestRate()).ignoreIfNull().notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("tenureInMonths").value(command.getTenureInMonths()).ignoreIfNull().notNull().integerGreaterThanZero();
@@ -234,7 +234,12 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
public DepositPermissionData retrieveDepositAccountsPermissions(DepositAccountData depositAccountData) {
boolean pendingApproval = (depositAccountData.getStatus().getId().equals(100L));
boolean undoApprovalAllowed = (depositAccountData.getStatus().getId().equals(300L));
boolean renewelAllowed = depositAccountData.isRenewalAllowed()&&(new LocalDate().isAfter(depositAccountData.getMaturedOn())||depositAccountData.getMaturedOn().isEqual(new LocalDate()));
boolean renewelAllowed = false;
if(depositAccountData.getMaturedOn()!=null){
if(new LocalDate().isAfter(depositAccountData.getMaturedOn())||depositAccountData.getMaturedOn().isEqual(new LocalDate())){
renewelAllowed = depositAccountData.isRenewalAllowed();
}
}
boolean rejectAllowed = pendingApproval;
boolean withdrawnByApplicantAllowed = pendingApproval;
boolean interestWithdrawAllowed = depositAccountData.isInterestWithdrawable();
@@ -40,4 +40,7 @@ public interface DepositAccountWritePlatformService {
@PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')")
EntityIdentifier renewDepositAccount(DepositAccountCommand command);
@PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')")
EntityIdentifier updateDepositAccount(DepositAccountCommand command);
}
@@ -293,7 +293,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
throw new DepositAccountNotFoundException(command.getAccountId());
}
if(new LocalDate().isBefore(account.maturesOnDate())){
if(command.getMaturesOnDate().isBefore(account.maturesOnDate())){
this.depositAccountAssembler.adjustTotalAmountForPreclosureInterest(account);
}
account.withdrawDepositAccountMoney(defaultDepositLifecycleStateMachine());
@@ -386,4 +386,32 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
throw new DepositAccountReopenException(account.getMaturityDate());
}
@Override
public EntityIdentifier updateDepositAccount(DepositAccountCommand command) {
try {
this.context.authenticatedUser();
DepositAccountCommandValidator validator = new DepositAccountCommandValidator(command);
validator.validateForUpdate();
DepositAccount account = this.depositAccountRepository.findOne(command.getId());
if (account == null || account.isDeleted()) {
throw new DepositAccountNotFoundException(command.getId());
}
if(account.getDepositStatus() == 100)
this.depositAccountAssembler.assembleUpdatedDepositAccount(account,command);
else if(account.getDepositStatus() == 300)
this.depositAccountAssembler.updateApprovedDepositAccount(account,command);
this.depositAccountRepository.save(account);
return new EntityIdentifier(account.getId());
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve);
return new EntityIdentifier(Long.valueOf(-1));
}
}
}
@@ -26,6 +26,7 @@ public class DepositStateTransitionApprovalCommandValidator {
baseDataValidator.reset().parameter("commencementDate").value(command.getEventDate()).notNull();
baseDataValidator.reset().parameter("deposit").value(command.getDepositAmount()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityInterestRate").value(command.getMaturityInterestRate()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("tenureInMonths").value(command.getTenureInMonths()).ignoreIfNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(command.getInterestCompoundedEveryPeriodType()).ignoreIfNull().inMinMaxRange(2, 2);