Mifosx-43 fixed bugs from pull #21
This commit is contained in:
+8
-4
@@ -22,6 +22,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.DepositStateTransitionApprovalCommand;
|
||||
import org.mifosng.platform.api.commands.DepositStateTransitionCommand;
|
||||
import org.mifosng.platform.api.commands.UndoStateTransitionCommand;
|
||||
import org.mifosng.platform.api.data.DepositAccountData;
|
||||
@@ -67,7 +68,7 @@ public class DepositAccountsApiResource {
|
||||
"deposit", "maturityInterestRate", "tenureInMonths",
|
||||
"interestCompoundedEvery",
|
||||
"interestCompoundedEveryPeriodType", "renewalAllowed",
|
||||
"preClosureAllowed", "preClosureInterestRate"));
|
||||
"preClosureAllowed", "preClosureInterestRate", "statusEnum","withdrawnonDate","rejectedonDate","closedonDate"));
|
||||
|
||||
|
||||
@POST
|
||||
@@ -187,23 +188,26 @@ public class DepositAccountsApiResource {
|
||||
public Response SubmitDepositApplication(@PathParam("accountId") final Long accountId,
|
||||
@QueryParam("command") final String commandParam, final String jsonRequestBody) {
|
||||
|
||||
DepositStateTransitionCommand command=apiDataConversionService.convertJsonToDepositStateTransitionCommand(accountId, jsonRequestBody);
|
||||
|
||||
|
||||
Response response=null;
|
||||
|
||||
if (is(commandParam, "approve")) {
|
||||
|
||||
|
||||
DepositStateTransitionApprovalCommand command=apiDataConversionService.convertJsonToDepositStateTransitionApprovalCommand(accountId, jsonRequestBody);
|
||||
EntityIdentifier identifier = this.depositAccountWritePlatformService.approveDepositApplication(command);
|
||||
response = Response.ok().entity(identifier).build();
|
||||
}
|
||||
|
||||
else if (is(commandParam, "reject")) {
|
||||
|
||||
DepositStateTransitionCommand command=apiDataConversionService.convertJsonToDepositStateTransitionCommand(accountId, jsonRequestBody);
|
||||
EntityIdentifier identifier = this.depositAccountWritePlatformService.rejectDepositApplication(command);
|
||||
response = Response.ok().entity(identifier).build();
|
||||
|
||||
} else if (is(commandParam, "withdrewbyclient")) {
|
||||
|
||||
|
||||
DepositStateTransitionCommand command=apiDataConversionService.convertJsonToDepositStateTransitionCommand(accountId, jsonRequestBody);
|
||||
EntityIdentifier identifier = this.depositAccountWritePlatformService.withdrawDepositApplication(command);
|
||||
response = Response.ok().entity(identifier).build();
|
||||
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package org.mifosng.platform.api.commands;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
public class DepositStateTransitionApprovalCommand {
|
||||
|
||||
private final Long accountId;
|
||||
private final Long productId;
|
||||
private final LocalDate eventDate;
|
||||
private final BigDecimal depositAmount;
|
||||
private final Integer tenureInMonths;
|
||||
private final Integer interestCompoundedEveryPeriodType;
|
||||
private final Integer interestCompoundedEvery;
|
||||
|
||||
public DepositStateTransitionApprovalCommand(Long resourceIdentifier, Long productId, LocalDate eventDate, Integer tenureInMonths, BigDecimal depositAmount, Integer interestCompoundedEveryPeriodType, Integer interestCompoundedEvery) {
|
||||
|
||||
this.accountId=resourceIdentifier;
|
||||
this.eventDate=eventDate;
|
||||
this.depositAmount=depositAmount;
|
||||
this.tenureInMonths=tenureInMonths;
|
||||
this.interestCompoundedEveryPeriodType=interestCompoundedEveryPeriodType;
|
||||
this.productId=productId;
|
||||
this.interestCompoundedEvery=interestCompoundedEvery;
|
||||
|
||||
}
|
||||
|
||||
public Long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public LocalDate getEventDate() {
|
||||
return eventDate;
|
||||
}
|
||||
|
||||
public BigDecimal getDepositAmount() {
|
||||
return depositAmount;
|
||||
}
|
||||
|
||||
public Integer getTenureInMonths() {
|
||||
return tenureInMonths;
|
||||
}
|
||||
|
||||
public Integer getInterestCompoundedEveryPeriodType() {
|
||||
return interestCompoundedEveryPeriodType;
|
||||
}
|
||||
|
||||
public Long getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public Integer getInterestCompoundedEvery() {
|
||||
return interestCompoundedEvery;
|
||||
}
|
||||
|
||||
}
|
||||
+35
-2
@@ -29,6 +29,9 @@ public class DepositAccountData {
|
||||
private final LocalDate actualCommencementDate;
|
||||
private final LocalDate projectedMaturityDate;
|
||||
private final LocalDate actualMaturityDate;
|
||||
private final LocalDate withdrawnonDate;
|
||||
private final LocalDate rejectedonDate;
|
||||
private final LocalDate closedonDate;
|
||||
private final BigDecimal projectedInterestAccrued;
|
||||
private final BigDecimal actualInterestAccrued;
|
||||
private final BigDecimal projectedMaturityAmount;
|
||||
@@ -41,7 +44,6 @@ public class DepositAccountData {
|
||||
private final BigDecimal preClosureInterestRate;
|
||||
|
||||
private final List<EnumOptionData> interestCompoundedEveryPeriodTypeOptions;
|
||||
|
||||
private final List<DepositProductLookup> productOptions;
|
||||
|
||||
/*
|
||||
@@ -81,6 +83,10 @@ public class DepositAccountData {
|
||||
|
||||
this.interestCompoundedEveryPeriodTypeOptions = new ArrayList<EnumOptionData>();
|
||||
this.productOptions = new ArrayList<DepositProductLookup>();
|
||||
|
||||
this.withdrawnonDate=null;
|
||||
this.closedonDate=null;
|
||||
this.rejectedonDate=null;
|
||||
}
|
||||
|
||||
public DepositAccountData(
|
||||
@@ -114,6 +120,10 @@ public class DepositAccountData {
|
||||
|
||||
this.interestCompoundedEveryPeriodTypeOptions = interestCompoundedEveryPeriodTypeOptions;
|
||||
this.productOptions = new ArrayList<DepositProductLookup>(productOptions);
|
||||
|
||||
this.withdrawnonDate=account.getWithdrawnonDate();
|
||||
this.rejectedonDate=account.getRejectedonDate();
|
||||
this.closedonDate=account.getClosedonDate();
|
||||
}
|
||||
|
||||
public DepositAccountData(
|
||||
@@ -139,7 +149,10 @@ public class DepositAccountData {
|
||||
final EnumOptionData interestCompoundedEveryPeriodType,
|
||||
final boolean renewalAllowed,
|
||||
final boolean preClosureAllowed,
|
||||
final BigDecimal preClosureInterestRate) {
|
||||
final BigDecimal preClosureInterestRate,
|
||||
final LocalDate withdrawnonDate,
|
||||
final LocalDate rejectedonDate,
|
||||
final LocalDate closedonDate) {
|
||||
this.id=id;
|
||||
this.externalId = externalId;
|
||||
this.status = status;
|
||||
@@ -167,6 +180,10 @@ public class DepositAccountData {
|
||||
|
||||
this.interestCompoundedEveryPeriodTypeOptions = new ArrayList<EnumOptionData>();
|
||||
this.productOptions = new ArrayList<DepositProductLookup>();
|
||||
|
||||
this.withdrawnonDate = withdrawnonDate;
|
||||
this.rejectedonDate = rejectedonDate;
|
||||
this.closedonDate = closedonDate;
|
||||
}
|
||||
|
||||
public DepositAccountData(
|
||||
@@ -209,6 +226,10 @@ public class DepositAccountData {
|
||||
|
||||
this.interestCompoundedEveryPeriodTypeOptions = new ArrayList<EnumOptionData>();
|
||||
this.productOptions = new ArrayList<DepositProductLookup>();
|
||||
|
||||
this.withdrawnonDate=null;
|
||||
this.closedonDate=null;
|
||||
this.rejectedonDate=null;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
@@ -314,4 +335,16 @@ public class DepositAccountData {
|
||||
public List<DepositProductLookup> getProductOptions() {
|
||||
return productOptions;
|
||||
}
|
||||
|
||||
public LocalDate getWithdrawnonDate() {
|
||||
return withdrawnonDate;
|
||||
}
|
||||
|
||||
public LocalDate getRejectedonDate() {
|
||||
return rejectedonDate;
|
||||
}
|
||||
|
||||
public LocalDate getClosedonDate() {
|
||||
return closedonDate;
|
||||
}
|
||||
}
|
||||
+3
@@ -6,6 +6,7 @@ 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.DepositProductCommand;
|
||||
import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand;
|
||||
import org.mifosng.platform.api.commands.DepositStateTransitionCommand;
|
||||
import org.mifosng.platform.api.commands.FundCommand;
|
||||
import org.mifosng.platform.api.commands.GroupCommand;
|
||||
@@ -60,4 +61,6 @@ public interface ApiDataConversionService {
|
||||
DepositAccountCommand convertJsonToDepositAccountCommand(Long resourceIdentifier, String jsonRequestBody);
|
||||
|
||||
DepositStateTransitionCommand convertJsonToDepositStateTransitionCommand(Long resourceIdentifier, String jsonRequestBody);
|
||||
|
||||
DepositStateTransitionApprovalCommand convertJsonToDepositStateTransitionApprovalCommand(Long resourceIdentifier, String jsonRequestBody);
|
||||
}
|
||||
+28
@@ -23,6 +23,7 @@ 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.DepositProductCommand;
|
||||
import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand;
|
||||
import org.mifosng.platform.api.commands.DepositStateTransitionCommand;
|
||||
import org.mifosng.platform.api.commands.FundCommand;
|
||||
import org.mifosng.platform.api.commands.GroupCommand;
|
||||
@@ -1027,4 +1028,31 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
|
||||
|
||||
return new DepositStateTransitionCommand(resourceIdentifier, eventDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DepositStateTransitionApprovalCommand convertJsonToDepositStateTransitionApprovalCommand(
|
||||
Long resourceIdentifier, String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) {
|
||||
throw new InvalidJsonException();
|
||||
}
|
||||
|
||||
Type typeOfMap = new TypeToken<Map<String, Object>>(){}.getType();
|
||||
Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap);
|
||||
|
||||
Set<String> supportedParams = new HashSet<String>( Arrays.asList("locale","eventDate", "dateFormat", "tenureInMonths", "depositAmount", "interestCompoundedEveryPeriodType", "productId","interestCompoundedEvery"));
|
||||
|
||||
checkForUnsupportedParameters(requestMap, supportedParams);
|
||||
|
||||
Set<String> modifiedParameters = new HashSet<String>();
|
||||
|
||||
LocalDate eventDate = extractLocalDateParameter("eventDate", requestMap, modifiedParameters);
|
||||
BigDecimal depositAmount=extractBigDecimalParameter("depositAmount", 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);
|
||||
|
||||
return new DepositStateTransitionApprovalCommand(resourceIdentifier, productId, eventDate, tenureInMonths, depositAmount, interestCompoundedEveryPeriodType,interestCompoundedEvery);
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -101,7 +101,8 @@ public class GoogleGsonApiJsonSerializerService implements
|
||||
"id", "externalId", "clientId", "clientName", "productId", "productName", "status",
|
||||
"currency", "deposit", "maturityInterestRate", "tenureInMonths",
|
||||
"interestCompoundedEvery", "interestCompoundedEveryPeriodType",
|
||||
"renewalAllowed","preClosureAllowed","preClosureInterestRate"
|
||||
"renewalAllowed","preClosureAllowed","preClosureInterestRate",
|
||||
"withdrawnonDate","rejectedonDate","closedonDate"
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
+22
-15
@@ -103,17 +103,17 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
@Column(name = "status_enum", nullable = false)
|
||||
private Integer depositStatus;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "closedon_date")
|
||||
private Date closedOnDate;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "rejectedon_date")
|
||||
private Date rejectedOnDate;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "withdrawnon_date")
|
||||
private Date withdrawnOnDate;
|
||||
private Date withdrawnOnDate;
|
||||
|
||||
public DepositAccount openNew(
|
||||
final Client client, final DepositProduct product,
|
||||
@@ -202,30 +202,37 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
}
|
||||
|
||||
public void approve(final LocalDate actualCommencementDate, DepositLifecycleStateMachine depositLifecycleStateMachine) {
|
||||
public void approve(final LocalDate actualCommencementDate, DepositLifecycleStateMachine depositLifecycleStateMachine, DepositApprovalData depositApprovalData, BigDecimal depositAmount) {
|
||||
|
||||
DepositStatus statusEnum = depositLifecycleStateMachine.transition(DepositEvent.DEPOSIT_APPROVED, DepositStatus.fromInt(this.depositStatus));
|
||||
this.depositStatus = statusEnum.getValue();
|
||||
|
||||
this.tenureInMonths = depositApprovalData.getTenureInMonths();
|
||||
this.depositAmount = depositAmount;
|
||||
this.interestCompoundedFrequencyType = depositApprovalData.getInterestCompoundedEveryPeriodType();
|
||||
|
||||
this.actualCommencementDate = actualCommencementDate
|
||||
.toDateTimeAtCurrentTime().toDate();
|
||||
this.actualCommencementDate = actualCommencementDate.toDateTimeAtCurrentTime().toDate();
|
||||
|
||||
if(this.actualCommencementDate != null)
|
||||
this.actualMaturityDate = new LocalDate(this.actualCommencementDate).plusMonths(this.tenureInMonths).toDate();
|
||||
|
||||
FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator = depositApprovalData.getFixedTermDepositInterestCalculator();
|
||||
|
||||
Money futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(depositApprovalData.getDeposit(), depositApprovalData.getTenureInMonths(),
|
||||
depositApprovalData.getMaturityInterestRate(), depositApprovalData.getInterestCompoundedEvery(), depositApprovalData.getInterestCompoundedEveryPeriodType());
|
||||
|
||||
this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.minus(depositApprovalData.getDeposit()).getAmount();
|
||||
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
|
||||
|
||||
|
||||
LocalDate submittalDate = new LocalDate(this.projectedCommencementDate);
|
||||
if (actualCommencementDate.isBefore(submittalDate)) {
|
||||
final String errorMessage = "The date on which a deposit is approved cannot be before its submittal date: "
|
||||
+ submittalDate.toString();
|
||||
throw new InvalidDepositStateTransitionException("approval",
|
||||
"cannot.be.before.submittal.date", errorMessage,
|
||||
getActualCommencementDate(), submittalDate);
|
||||
final String errorMessage = "The date on which a deposit is approved cannot be before its submittal date: " + submittalDate.toString();
|
||||
throw new InvalidDepositStateTransitionException("approval", "cannot.be.before.submittal.date", errorMessage, getActualCommencementDate(), submittalDate);
|
||||
}
|
||||
if (actualCommencementDate.isAfter(new LocalDate())) {
|
||||
final String errorMessage = "The date on which a deposit is approved cannot be in the future.";
|
||||
throw new InvalidDepositStateTransitionException("approval",
|
||||
"cannot.be.a.future.date", errorMessage,
|
||||
getActualCommencementDate());
|
||||
throw new InvalidDepositStateTransitionException("approval", "cannot.be.a.future.date", errorMessage, getActualCommencementDate());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package org.mifosng.platform.saving.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.mifosng.platform.currency.domain.Money;
|
||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||
|
||||
public class DepositApprovalData {
|
||||
|
||||
private final Integer tenureInMonths;
|
||||
private final Money deposit;
|
||||
private final BigDecimal maturityInterestRate;
|
||||
private final Integer interestCompoundedEvery;
|
||||
private final PeriodFrequencyType interestCompoundedEveryPeriodType;
|
||||
private final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator;
|
||||
|
||||
|
||||
public DepositApprovalData(final Integer tenureInMonths,final Money deposit,final BigDecimal maturityInterestRate,final Integer interestCompoundedEvery,final PeriodFrequencyType interestCompoundedEveryPeriodType,final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator) {
|
||||
this.tenureInMonths=tenureInMonths;
|
||||
this.deposit=deposit;
|
||||
this.maturityInterestRate=maturityInterestRate;
|
||||
this.interestCompoundedEvery=interestCompoundedEvery;
|
||||
this.interestCompoundedEveryPeriodType=interestCompoundedEveryPeriodType;
|
||||
this.fixedTermDepositInterestCalculator=fixedTermDepositInterestCalculator;
|
||||
}
|
||||
|
||||
|
||||
public Integer getTenureInMonths() {
|
||||
return tenureInMonths;
|
||||
}
|
||||
public Money getDeposit() {
|
||||
return deposit;
|
||||
}
|
||||
public BigDecimal getMaturityInterestRate() {
|
||||
return maturityInterestRate;
|
||||
}
|
||||
public Integer getInterestCompoundedEvery() {
|
||||
return interestCompoundedEvery;
|
||||
}
|
||||
public PeriodFrequencyType getInterestCompoundedEveryPeriodType() {
|
||||
return interestCompoundedEveryPeriodType;
|
||||
}
|
||||
public FixedTermDepositInterestCalculator getFixedTermDepositInterestCalculator() {
|
||||
return fixedTermDepositInterestCalculator;
|
||||
}
|
||||
|
||||
}
|
||||
+22
-2
@@ -2,6 +2,8 @@ package org.mifosng.platform.saving.domain;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosng.platform.exceptions.InvalidDepositStateTransitionException;
|
||||
|
||||
public class DepositLifecycleStateMachineImpl implements
|
||||
DepositLifecycleStateMachine {
|
||||
|
||||
@@ -26,28 +28,46 @@ public class DepositLifecycleStateMachineImpl implements
|
||||
if (from.hasStateOf(DepositStatus.SUBMITED_AND_PENDING_APPROVAL)) {
|
||||
newState = stateOf(DepositStatus.REJECTED, allowedDepositStatuses);
|
||||
}
|
||||
else{
|
||||
final String errorMessage = "The DepositApplication can not be rejected from "+from.getCode() ;
|
||||
throw new InvalidDepositStateTransitionException("rejection", "failed", errorMessage,from);
|
||||
}
|
||||
break;
|
||||
case DEPOSIT_APPROVED:
|
||||
if (from.hasStateOf(DepositStatus.SUBMITED_AND_PENDING_APPROVAL)) {
|
||||
newState = stateOf(DepositStatus.APPROVED, allowedDepositStatuses);
|
||||
}
|
||||
else{
|
||||
final String errorMessage = "The DepositApplication can not be approved from "+from.getCode() ;
|
||||
throw new InvalidDepositStateTransitionException("approve", "failed", errorMessage,from);
|
||||
}
|
||||
break;
|
||||
case DEPOSIT_WITHDRAWN:
|
||||
if (this.anyOfAllowedWhenComingFrom(from, DepositStatus.SUBMITED_AND_PENDING_APPROVAL, DepositStatus.APPROVED)) {
|
||||
newState = stateOf(DepositStatus.WITHDRAWN_BY_CLIENT, allowedDepositStatuses);
|
||||
}
|
||||
else{
|
||||
final String errorMessage = "The DepositApplication can not be withdrawn from "+from.getCode() ;
|
||||
throw new InvalidDepositStateTransitionException("withdrawbyclient", "failed", errorMessage,from);
|
||||
}
|
||||
break;
|
||||
case DEPOSIT_APPROVAL_UNDO:
|
||||
if (from.hasStateOf(DepositStatus.APPROVED)) {
|
||||
newState = stateOf(DepositStatus.SUBMITED_AND_PENDING_APPROVAL, allowedDepositStatuses);
|
||||
}
|
||||
else{
|
||||
final String errorMessage = "The DepositApplication can not be unapproved from "+from.getCode() ;
|
||||
throw new InvalidDepositStateTransitionException("unapprove", "failed", errorMessage,from);
|
||||
}
|
||||
break;
|
||||
case DEPOSIT_MATURED:
|
||||
if (from.hasStateOf(DepositStatus.APPROVED) ){
|
||||
newState = stateOf(DepositStatus.MATURED, allowedDepositStatuses);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
else{
|
||||
final String errorMessage = "The DepositApplication can not be matured from "+from.getCode() ;
|
||||
throw new InvalidDepositStateTransitionException("mature", "failed", errorMessage,from);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+26
@@ -4,14 +4,18 @@ 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.api.commands.DepositStateTransitionApprovalCommand;
|
||||
import org.mifosng.platform.client.domain.Client;
|
||||
import org.mifosng.platform.client.domain.ClientRepository;
|
||||
import org.mifosng.platform.currency.domain.Money;
|
||||
import org.mifosng.platform.exceptions.ClientNotFoundException;
|
||||
import org.mifosng.platform.exceptions.DepositProductNotFoundException;
|
||||
import org.mifosng.platform.exceptions.NoAuthorizationException;
|
||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||
import org.mifosng.platform.saving.domain.DepositAccount;
|
||||
import org.mifosng.platform.saving.domain.DepositApprovalData;
|
||||
import org.mifosng.platform.saving.domain.DepositLifecycleStateMachine;
|
||||
import org.mifosng.platform.saving.domain.DepositLifecycleStateMachineImpl;
|
||||
import org.mifosng.platform.saving.domain.DepositStatus;
|
||||
@@ -95,6 +99,28 @@ public class DepositAccountAssembler {
|
||||
return account;
|
||||
}
|
||||
|
||||
public DepositApprovalData assembleFrom(DepositStateTransitionApprovalCommand command){
|
||||
|
||||
DepositProduct product = this.depositProductRepository.findOne(command.getProductId());
|
||||
if (product == null || product.isDeleted()) {
|
||||
throw new DepositProductNotFoundException(command.getProductId());
|
||||
}
|
||||
|
||||
PeriodFrequencyType interestCompoundedEveryPeriodType= product.getInterestCompoundedEveryPeriodType();
|
||||
if (command.getInterestCompoundedEveryPeriodType() != null) {
|
||||
interestCompoundedEveryPeriodType = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType());
|
||||
}
|
||||
|
||||
Integer tenureInMonths = command.getTenureInMonths();
|
||||
Money deposit = Money.of(product.getCurrency(), command.getDepositAmount());
|
||||
BigDecimal maturityInterestRate = product.getMaturityDefaultInterestRate();
|
||||
Integer interestCompoundedEvery = product.getInterestCompoundedEvery();
|
||||
|
||||
return new DepositApprovalData(tenureInMonths, deposit, maturityInterestRate, interestCompoundedEvery, interestCompoundedEveryPeriodType, this.fixedTermDepositInterestCalculator);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private DepositLifecycleStateMachine defaultDepositLifecycleStateMachine() {
|
||||
List<DepositStatus> allowedDepositStatuses = Arrays.asList(DepositStatus.values());
|
||||
return new DepositLifecycleStateMachineImpl(allowedDepositStatuses);
|
||||
|
||||
+8
-2
@@ -115,7 +115,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
||||
private static final class DepositAccountMapper implements RowMapper<DepositAccountData> {
|
||||
|
||||
public String schema() {
|
||||
return "da.id as id, da.external_id as externalId, da.client_id as clientId, da.product_id as productId,"
|
||||
return "da.id as id, da.external_id as externalId, da.client_id as clientId, da.product_id as productId, "
|
||||
+ " da.currency_code as currencyCode, da.currency_digits as currencyDigits, "
|
||||
+ " da.deposit_amount as depositAmount, da.status_enum as statusId, "
|
||||
+ " da.maturity_nominal_interest_rate as interestRate, da.tenure_months as termInMonths, da.projected_commencement_date as projectedCommencementDate,"
|
||||
@@ -124,6 +124,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
||||
+ " da.projected_total_maturity_amount as projectedMaturityAmount, da.actual_total_amount as actualMaturityAmount, "
|
||||
+ " da.interest_compounded_every as interestCompoundedEvery, da.interest_compounded_every_period_enum as interestCompoundedEveryPeriodType, "
|
||||
+ " da.is_renewal_allowed as renewalAllowed, da.is_preclosure_allowed as preClosureAllowed, da.pre_closure_interest_rate as preClosureInterestRate, "
|
||||
+ " da.withdrawnon_date as withdrawnonDate, da.rejectedon_date as rejectedonDate, da.closedon_date as closedonDate, "
|
||||
+ " c.firstname as firstname, c.lastname as lastname, pd.name as productName,"
|
||||
+ " curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol"
|
||||
+ " from m_deposit_account da "
|
||||
@@ -177,11 +178,16 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
||||
|
||||
BigDecimal preClosureInterestRate = rs.getBigDecimal("preClosureInterestRate");
|
||||
|
||||
LocalDate withdrawnonDate = JdbcSupport.getLocalDate(rs, "withdrawnonDate");
|
||||
LocalDate rejectedonDate = JdbcSupport.getLocalDate(rs, "rejectedonDate");
|
||||
LocalDate closedonDate = JdbcSupport.getLocalDate(rs, "closedonDate");
|
||||
|
||||
return new DepositAccountData(id, externalId, status, clientId, clientName, productId, productName, currencyData, depositAmount,
|
||||
interestRate, termInMonths, projectedCommencementDate, actualCommencementDate, projectedMaturityDate, actualMaturityDate,
|
||||
projectedInterestAccrued, actualInterestAccrued, projectedMaturityAmount, actualMaturityAmount,
|
||||
interestCompoundedEvery, interestCompoundedEveryPeriodType,
|
||||
renewalAllowed, preClosureAllowed, preClosureInterestRate);
|
||||
renewalAllowed, preClosureAllowed, preClosureInterestRate,
|
||||
withdrawnonDate,rejectedonDate,closedonDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
package org.mifosng.platform.saving.service;
|
||||
|
||||
import org.mifosng.platform.api.commands.DepositAccountCommand;
|
||||
import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand;
|
||||
import org.mifosng.platform.api.commands.DepositStateTransitionCommand;
|
||||
import org.mifosng.platform.api.commands.UndoStateTransitionCommand;
|
||||
import org.mifosng.platform.api.data.EntityIdentifier;
|
||||
@@ -18,7 +19,7 @@ public interface DepositAccountWritePlatformService {
|
||||
EntityIdentifier deleteDepositAccount(Long productId);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_APPROVE_DEPOSIT_ROLE', 'CAN_APPROVE_DEPOSIT_IN_THE_PAST_ROLE')")
|
||||
EntityIdentifier approveDepositApplication(DepositStateTransitionCommand command);
|
||||
EntityIdentifier approveDepositApplication(DepositStateTransitionApprovalCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_APPROVE_DEPOSIT_ROLE', 'CAN_APPROVE_DEPOSIT_IN_THE_PAST_ROLE')")
|
||||
EntityIdentifier rejectDepositApplication(DepositStateTransitionCommand command);
|
||||
|
||||
+12
-5
@@ -1,10 +1,12 @@
|
||||
package org.mifosng.platform.saving.service;
|
||||
|
||||
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.api.commands.DepositStateTransitionApprovalCommand;
|
||||
import org.mifosng.platform.api.commands.DepositStateTransitionCommand;
|
||||
import org.mifosng.platform.api.commands.UndoStateTransitionCommand;
|
||||
import org.mifosng.platform.api.data.EntityIdentifier;
|
||||
@@ -14,6 +16,7 @@ import org.mifosng.platform.exceptions.PlatformDataIntegrityException;
|
||||
import org.mifosng.platform.exceptions.ProductNotFoundException;
|
||||
import org.mifosng.platform.saving.domain.DepositAccount;
|
||||
import org.mifosng.platform.saving.domain.DepositAccountRepository;
|
||||
import org.mifosng.platform.saving.domain.DepositApprovalData;
|
||||
import org.mifosng.platform.saving.domain.DepositLifecycleStateMachine;
|
||||
import org.mifosng.platform.saving.domain.DepositLifecycleStateMachineImpl;
|
||||
import org.mifosng.platform.saving.domain.DepositStatus;
|
||||
@@ -126,11 +129,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier approveDepositApplication(DepositStateTransitionCommand command) {
|
||||
public EntityIdentifier approveDepositApplication(DepositStateTransitionApprovalCommand command) {
|
||||
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
|
||||
DepositStateTransitionCommandValidator validator = new DepositStateTransitionCommandValidator(command);
|
||||
DepositStateTransitionApprovalCommandValidator validator = new DepositStateTransitionApprovalCommandValidator(command);
|
||||
validator.validate();
|
||||
|
||||
|
||||
@@ -139,12 +142,16 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
throw new DepositAccountNotFoundException(command.getAccountId());
|
||||
}
|
||||
|
||||
DepositApprovalData depositApprovalData=this.depositAccountAssembler.assembleFrom(command);
|
||||
|
||||
LocalDate eventDate = command.getEventDate();
|
||||
if (this.isBeforeToday(eventDate) && currentUser.canNotApproveLoanInPast()) {
|
||||
throw new NoAuthorizationException("User has no authority to approve deposit with a date in the past.");
|
||||
}
|
||||
|
||||
account.approve(eventDate, defaultDepositLifecycleStateMachine());
|
||||
BigDecimal depositAmount = command.getDepositAmount();
|
||||
|
||||
account.approve(eventDate, defaultDepositLifecycleStateMachine(), depositApprovalData,depositAmount);
|
||||
this.depositAccountRepository.save(account);
|
||||
|
||||
return new EntityIdentifier(account.getId());
|
||||
@@ -204,7 +211,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
}
|
||||
|
||||
account.withdraw(eventDate, defaultDepositLifecycleStateMachine());
|
||||
return null;
|
||||
return new EntityIdentifier(account.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -221,6 +228,6 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
account.undoDepositApproval(defaultDepositLifecycleStateMachine());
|
||||
this.depositAccountRepository.save(account);
|
||||
|
||||
return null;
|
||||
return new EntityIdentifier(account.getId());
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
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.DepositStateTransitionApprovalCommand;
|
||||
import org.mifosng.platform.api.data.ApiParameterError;
|
||||
import org.mifosng.platform.exceptions.PlatformApiDataValidationException;
|
||||
|
||||
public class DepositStateTransitionApprovalCommandValidator {
|
||||
|
||||
|
||||
|
||||
private final DepositStateTransitionApprovalCommand command;
|
||||
|
||||
public DepositStateTransitionApprovalCommandValidator(final DepositStateTransitionApprovalCommand command) {
|
||||
this.command=command;
|
||||
}
|
||||
|
||||
public void validate(){
|
||||
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.transition");
|
||||
baseDataValidator.reset().parameter("accountId").value(command.getAccountId()).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter("eventDate").value(command.getEventDate()).notNull();
|
||||
|
||||
baseDataValidator.reset().parameter("depositAmount").value(command.getDepositAmount()).notNull().zeroOrPositiveAmount();
|
||||
baseDataValidator.reset().parameter("tenureInMonths").value(command.getTenureInMonths()).ignoreIfNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(command.getInterestCompoundedEveryPeriodType()).ignoreIfNull().inMinMaxRange(2, 2);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user