wip:enabling transfer of saving accounts
This commit is contained in:
+3
-2
@@ -108,7 +108,7 @@ public class AccountingConstants {
|
|||||||
|
|
||||||
/*** Accounting placeholders for cash based accounting for savings products ***/
|
/*** Accounting placeholders for cash based accounting for savings products ***/
|
||||||
public static enum CASH_ACCOUNTS_FOR_SAVINGS {
|
public static enum CASH_ACCOUNTS_FOR_SAVINGS {
|
||||||
SAVINGS_REFERENCE(1), SAVINGS_CONTROL(2), INTEREST_ON_SAVINGS(3), INCOME_FROM_FEES(4);
|
SAVINGS_REFERENCE(1), SAVINGS_CONTROL(2), INTEREST_ON_SAVINGS(3), INCOME_FROM_FEES(4), TRANSFERS_SUSPENSE(10);
|
||||||
|
|
||||||
private final Integer value;
|
private final Integer value;
|
||||||
|
|
||||||
@@ -145,7 +145,8 @@ public class AccountingConstants {
|
|||||||
public static enum SAVINGS_PRODUCT_ACCOUNTING_PARAMS {
|
public static enum SAVINGS_PRODUCT_ACCOUNTING_PARAMS {
|
||||||
SAVINGS_REFERENCE("savingsReferenceAccountId"), SAVINGS_CONTROL("savingsControlAccountId"), INCOME_FROM_FEES(
|
SAVINGS_REFERENCE("savingsReferenceAccountId"), SAVINGS_CONTROL("savingsControlAccountId"), INCOME_FROM_FEES(
|
||||||
"incomeFromFeeAccountId"), INTEREST_ON_SAVINGS("interestOnSavingsAccountId"), PAYMENT_CHANNEL_FUND_SOURCE_MAPPING(
|
"incomeFromFeeAccountId"), INTEREST_ON_SAVINGS("interestOnSavingsAccountId"), PAYMENT_CHANNEL_FUND_SOURCE_MAPPING(
|
||||||
"paymentChannelToFundSourceMappings"), PAYMENT_TYPE("paymentTypeId"), FUND_SOURCE("fundSourceAccountId");
|
"paymentChannelToFundSourceMappings"), PAYMENT_TYPE("paymentTypeId"), FUND_SOURCE("fundSourceAccountId"), TRANSFERS_SUSPENSE(
|
||||||
|
"transfersInSuspenseAccountId");
|
||||||
|
|
||||||
private final String value;
|
private final String value;
|
||||||
|
|
||||||
|
|||||||
+15
@@ -72,6 +72,21 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
|
|||||||
transactionDate, amount, isReversal);
|
transactionDate, amount, isReversal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Handle Transfers proposal **/
|
||||||
|
else if (savingsTransactionDTO.getTransactionType().isInitiateTransfer()) {
|
||||||
|
helper.createCashBasedJournalEntriesAndReversalsForSavings(office, CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL,
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.TRANSFERS_SUSPENSE, savingsProductId, paymentTypeId, savingsId, transactionId,
|
||||||
|
transactionDate, amount, isReversal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handle Transfer Withdrawal or Acceptance **/
|
||||||
|
else if (savingsTransactionDTO.getTransactionType().isWithdrawTransfer()
|
||||||
|
|| savingsTransactionDTO.getTransactionType().isApproveTransfer()) {
|
||||||
|
helper.createCashBasedJournalEntriesAndReversalsForSavings(office, CASH_ACCOUNTS_FOR_SAVINGS.TRANSFERS_SUSPENSE,
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL, savingsProductId, paymentTypeId, savingsId, transactionId,
|
||||||
|
transactionDate, amount, isReversal);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -156,6 +156,11 @@ public final class ProductToGLAccountMappingFromApiJsonDeserializer {
|
|||||||
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue())
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue())
|
||||||
.value(savingsReferenceAccountId).notNull().integerGreaterThanZero();
|
.value(savingsReferenceAccountId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long transfersInSuspenseAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue())
|
||||||
|
.value(transfersInSuspenseAccountId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
final Long interestOnSavingsAccountId = fromApiJsonHelper.extractLongNamed(
|
final Long interestOnSavingsAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
|
||||||
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue())
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue())
|
||||||
|
|||||||
+2
@@ -169,6 +169,8 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), glAccountId);
|
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), glAccountId);
|
||||||
} else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_FEES)) {
|
} else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_FEES)) {
|
||||||
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), glAccountId);
|
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), glAccountId);
|
||||||
|
} else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.TRANSFERS_SUSPENSE)) {
|
||||||
|
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), glAccountId);
|
||||||
} else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.INTEREST_ON_SAVINGS)) {
|
} else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.INTEREST_ON_SAVINGS)) {
|
||||||
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), glAccountId);
|
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), glAccountId);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -163,6 +163,9 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
|
|||||||
savingsProductToGLAccountMappingHelper.saveSavingsToLiabilityAccountMapping(element,
|
savingsProductToGLAccountMappingHelper.saveSavingsToLiabilityAccountMapping(element,
|
||||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), savingProductId,
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), savingProductId,
|
||||||
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL.getValue());
|
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL.getValue());
|
||||||
|
savingsProductToGLAccountMappingHelper.saveSavingsToLiabilityAccountMapping(element,
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), savingProductId,
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.TRANSFERS_SUSPENSE.getValue());
|
||||||
|
|
||||||
// advanced accounting mappings
|
// advanced accounting mappings
|
||||||
savingsProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, savingProductId, null);
|
savingsProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, savingProductId, null);
|
||||||
|
|||||||
+6
@@ -106,6 +106,8 @@ public class SavingsProductToGLAccountMappingHelper extends ProductToGLAccountMa
|
|||||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
|
||||||
final Long savingsControlId = this.fromApiJsonHelper.extractLongNamed(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(),
|
final Long savingsControlId = this.fromApiJsonHelper.extractLongNamed(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(),
|
||||||
element);
|
element);
|
||||||
|
final Long transfersInSuspenseAccountId = this.fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), element);
|
||||||
|
|
||||||
switch (accountingRuleType) {
|
switch (accountingRuleType) {
|
||||||
case NONE:
|
case NONE:
|
||||||
@@ -115,6 +117,7 @@ public class SavingsProductToGLAccountMappingHelper extends ProductToGLAccountMa
|
|||||||
changes.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(), savingsReferenceId);
|
changes.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(), savingsReferenceId);
|
||||||
changes.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), interestOnSavingsId);
|
changes.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), interestOnSavingsId);
|
||||||
changes.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), incomeFromFeesId);
|
changes.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), incomeFromFeesId);
|
||||||
|
changes.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), transfersInSuspenseAccountId);
|
||||||
break;
|
break;
|
||||||
case ACCRUAL_BASED:
|
case ACCRUAL_BASED:
|
||||||
break;
|
break;
|
||||||
@@ -156,6 +159,9 @@ public class SavingsProductToGLAccountMappingHelper extends ProductToGLAccountMa
|
|||||||
mergeSavingsToLiabilityAccountMappingChanges(element, SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(),
|
mergeSavingsToLiabilityAccountMappingChanges(element, SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(),
|
||||||
savingsProductId, CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL.getValue(),
|
savingsProductId, CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL.getValue(),
|
||||||
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL.toString(), changes);
|
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL.toString(), changes);
|
||||||
|
mergeSavingsToLiabilityAccountMappingChanges(element, SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(),
|
||||||
|
savingsProductId, CASH_ACCOUNTS_FOR_SAVINGS.TRANSFERS_SUSPENSE.getValue(),
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.TRANSFERS_SUSPENSE.toString(), changes);
|
||||||
break;
|
break;
|
||||||
case ACCRUAL_BASED:
|
case ACCRUAL_BASED:
|
||||||
break;
|
break;
|
||||||
|
|||||||
+4
-4
@@ -125,18 +125,18 @@ public enum LoanStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTransferInProgress() {
|
public boolean isTransferInProgress() {
|
||||||
return this.isTransferInProgress();
|
return this.value.equals(LoanStatus.TRANSFER_IN_PROGRESS.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTransferOnHold() {
|
public boolean isTransferOnHold() {
|
||||||
return this.isTransferOnHold();
|
return this.value.equals(LoanStatus.TRANSFER_ON_HOLD.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUnderTransfer() {
|
public boolean isUnderTransfer() {
|
||||||
return isTransferInProgress() || isTransferOnHold();
|
return isTransferInProgress() || isTransferOnHold();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOverpaid(){
|
public boolean isOverpaid() {
|
||||||
return this.value.equals(LoanStatus.OVERPAID.getValue());
|
return this.value.equals(LoanStatus.OVERPAID.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -138,7 +138,7 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction withdrawTransfer(final Office office, final Loan loan, final LocalDate transferDate) {
|
public static LoanTransaction withdrawTransfer(final Office office, final Loan loan, final LocalDate transferDate) {
|
||||||
return new LoanTransaction(loan, office, LoanTransactionType.APPROVE_TRANSFER.getValue(), transferDate.toDateMidnight().toDate(),
|
return new LoanTransaction(loan, office, LoanTransactionType.WITHDRAW_TRANSFER.getValue(), transferDate.toDateMidnight().toDate(),
|
||||||
loan.getSummary().getTotalOutstanding(), loan.getSummary().getTotalPrincipalOutstanding(), loan.getSummary()
|
loan.getSummary().getTotalOutstanding(), loan.getSummary().getTotalPrincipalOutstanding(), loan.getSummary()
|
||||||
.getTotalInterestOutstanding(), loan.getSummary().getTotalFeeChargesOutstanding(), loan.getSummary()
|
.getTotalInterestOutstanding(), loan.getSummary().getTotalFeeChargesOutstanding(), loan.getSummary()
|
||||||
.getTotalPenaltyChargesOutstanding(), false, null);
|
.getTotalPenaltyChargesOutstanding(), false, null);
|
||||||
|
|||||||
+1
-1
@@ -357,7 +357,7 @@ public class LoanEnumerations {
|
|||||||
break;
|
break;
|
||||||
case TRANSFER_ON_HOLD:
|
case TRANSFER_ON_HOLD:
|
||||||
optionData = new LoanStatusEnumData(LoanStatus.TRANSFER_ON_HOLD.getValue().longValue(),
|
optionData = new LoanStatusEnumData(LoanStatus.TRANSFER_ON_HOLD.getValue().longValue(),
|
||||||
LoanStatus.TRANSFER_ON_HOLD.getCode(), "Transfer in hold");
|
LoanStatus.TRANSFER_ON_HOLD.getCode(), "Transfer on hold");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
+17
-1
@@ -18,7 +18,11 @@ public enum SavingsAccountTransactionType {
|
|||||||
WITHDRAWAL(2, "savingsAccountTransactionType.withdrawal"), //
|
WITHDRAWAL(2, "savingsAccountTransactionType.withdrawal"), //
|
||||||
INTEREST_POSTING(3, "savingsAccountTransactionType.interestPosting"), //
|
INTEREST_POSTING(3, "savingsAccountTransactionType.interestPosting"), //
|
||||||
WITHDRAWAL_FEE(4, "savingsAccountTransactionType.withdrawalFee"), //
|
WITHDRAWAL_FEE(4, "savingsAccountTransactionType.withdrawalFee"), //
|
||||||
ANNUAL_FEE(5, "savingsAccountTransactionType.annualFee");
|
ANNUAL_FEE(5, "savingsAccountTransactionType.annualFee"), //
|
||||||
|
INITIATE_TRANSFER(12, "savingsAccountTransactionType.initiateTransfer"), //
|
||||||
|
APPROVE_TRANSFER(13, "savingsAccountTransactionType.approveTransfer"), //
|
||||||
|
WITHDRAW_TRANSFER(14, "savingsAccountTransactionType.withdrawTransfer"), //
|
||||||
|
REJECT_TRANSFER(15, "savingsAccountTransactionType.rejectTransfer");
|
||||||
|
|
||||||
private final Integer value;
|
private final Integer value;
|
||||||
private final String code;
|
private final String code;
|
||||||
@@ -57,6 +61,18 @@ public enum SavingsAccountTransactionType {
|
|||||||
case 5:
|
case 5:
|
||||||
loanTransactionType = SavingsAccountTransactionType.ANNUAL_FEE;
|
loanTransactionType = SavingsAccountTransactionType.ANNUAL_FEE;
|
||||||
break;
|
break;
|
||||||
|
case 12:
|
||||||
|
loanTransactionType = SavingsAccountTransactionType.INITIATE_TRANSFER;
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
loanTransactionType = SavingsAccountTransactionType.APPROVE_TRANSFER;
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
loanTransactionType = SavingsAccountTransactionType.WITHDRAW_TRANSFER;
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
loanTransactionType = SavingsAccountTransactionType.REJECT_TRANSFER;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return loanTransactionType;
|
return loanTransactionType;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -105,7 +105,8 @@ public class SavingsApiConstants {
|
|||||||
annualFeeOnMonthDayParamName, accountingRuleParamName, SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
|
annualFeeOnMonthDayParamName, accountingRuleParamName, SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
|
||||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(),
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(),
|
||||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
|
||||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue()));
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(),
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue()));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These parameters will match the class level parameters of
|
* These parameters will match the class level parameters of
|
||||||
|
|||||||
+8
-1
@@ -27,9 +27,14 @@ public class SavingsAccountStatusEnumData {
|
|||||||
private final boolean active;
|
private final boolean active;
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private final boolean closed;
|
private final boolean closed;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final boolean transferInProgress;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final boolean transferOnHold;
|
||||||
|
|
||||||
public SavingsAccountStatusEnumData(final Long id, final String code, final String value, final boolean submittedAndPendingApproval,
|
public SavingsAccountStatusEnumData(final Long id, final String code, final String value, final boolean submittedAndPendingApproval,
|
||||||
final boolean approved, final boolean rejected, final boolean withdrawnByApplicant, final boolean active, final boolean closed) {
|
final boolean approved, final boolean rejected, final boolean withdrawnByApplicant, final boolean active, final boolean closed,
|
||||||
|
final boolean transferInProgress, final boolean transferOnHold) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
@@ -39,6 +44,8 @@ public class SavingsAccountStatusEnumData {
|
|||||||
this.withdrawnByApplicant = withdrawnByApplicant;
|
this.withdrawnByApplicant = withdrawnByApplicant;
|
||||||
this.active = active;
|
this.active = active;
|
||||||
this.closed = closed;
|
this.closed = closed;
|
||||||
|
this.transferInProgress = transferInProgress;
|
||||||
|
this.transferOnHold = transferOnHold;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long id() {
|
public Long id() {
|
||||||
|
|||||||
+24
@@ -22,6 +22,10 @@ public class SavingsAccountTransactionEnumData {
|
|||||||
private final boolean withdrawal;
|
private final boolean withdrawal;
|
||||||
private final boolean interestPosting;
|
private final boolean interestPosting;
|
||||||
private final boolean feeDeduction;
|
private final boolean feeDeduction;
|
||||||
|
private final boolean initiateTransfer;
|
||||||
|
private final boolean approveTransfer;
|
||||||
|
private final boolean withdrawTransfer;
|
||||||
|
private final boolean rejectTransfer;
|
||||||
|
|
||||||
public SavingsAccountTransactionEnumData(final Long id, final String code, final String value) {
|
public SavingsAccountTransactionEnumData(final Long id, final String code, final String value) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@@ -32,6 +36,10 @@ public class SavingsAccountTransactionEnumData {
|
|||||||
this.interestPosting = Long.valueOf(SavingsAccountTransactionType.INTEREST_POSTING.getValue()).equals(this.id);
|
this.interestPosting = Long.valueOf(SavingsAccountTransactionType.INTEREST_POSTING.getValue()).equals(this.id);
|
||||||
this.feeDeduction = Long.valueOf(SavingsAccountTransactionType.ANNUAL_FEE.getValue()).equals(this.id)
|
this.feeDeduction = Long.valueOf(SavingsAccountTransactionType.ANNUAL_FEE.getValue()).equals(this.id)
|
||||||
|| Long.valueOf(SavingsAccountTransactionType.WITHDRAWAL_FEE.getValue()).equals(this.id);
|
|| Long.valueOf(SavingsAccountTransactionType.WITHDRAWAL_FEE.getValue()).equals(this.id);
|
||||||
|
this.initiateTransfer = Long.valueOf(SavingsAccountTransactionType.INITIATE_TRANSFER.getValue()).equals(this.id);
|
||||||
|
this.approveTransfer = Long.valueOf(SavingsAccountTransactionType.APPROVE_TRANSFER.getValue()).equals(this.id);
|
||||||
|
this.withdrawTransfer = Long.valueOf(SavingsAccountTransactionType.WITHDRAW_TRANSFER.getValue()).equals(this.id);
|
||||||
|
this.rejectTransfer = Long.valueOf(SavingsAccountTransactionType.REJECT_TRANSFER.getValue()).equals(this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDeposit() {
|
public boolean isDeposit() {
|
||||||
@@ -54,4 +62,20 @@ public class SavingsAccountTransactionEnumData {
|
|||||||
return this.feeDeduction;
|
return this.feeDeduction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isInitiateTransfer() {
|
||||||
|
return this.initiateTransfer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isApproveTransfer() {
|
||||||
|
return this.approveTransfer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWithdrawTransfer() {
|
||||||
|
return this.withdrawTransfer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRejectTransfer() {
|
||||||
|
return this.rejectTransfer;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+22
-10
@@ -174,11 +174,12 @@ public class SavingsProductDataValidator {
|
|||||||
.zeroOrPositiveAmount();
|
.zeroOrPositiveAmount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.fromApiJsonHelper.parameterExists(withdrawalFeeForTransfersParamName, element)) {
|
if (this.fromApiJsonHelper.parameterExists(withdrawalFeeForTransfersParamName, element)) {
|
||||||
final Boolean isWithdrawalFeeApplicableForTransfers = fromApiJsonHelper.extractBooleanNamed(withdrawalFeeForTransfersParamName, element);
|
final Boolean isWithdrawalFeeApplicableForTransfers = fromApiJsonHelper.extractBooleanNamed(withdrawalFeeForTransfersParamName,
|
||||||
baseDataValidator.reset().parameter(withdrawalFeeForTransfersParamName).value(isWithdrawalFeeApplicableForTransfers).ignoreIfNull()
|
element);
|
||||||
.validateForBooleanValue();
|
baseDataValidator.reset().parameter(withdrawalFeeForTransfersParamName).value(isWithdrawalFeeApplicableForTransfers)
|
||||||
|
.ignoreIfNull().validateForBooleanValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.fromApiJsonHelper.parameterExists(annualFeeAmountParamName, element)) {
|
if (this.fromApiJsonHelper.parameterExists(annualFeeAmountParamName, element)) {
|
||||||
@@ -216,6 +217,11 @@ public class SavingsProductDataValidator {
|
|||||||
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue())
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue())
|
||||||
.value(savingsReferenceAccountId).notNull().integerGreaterThanZero();
|
.value(savingsReferenceAccountId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long transfersInSuspenseAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue())
|
||||||
|
.value(transfersInSuspenseAccountId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
final Long interestOnSavingsAccountId = fromApiJsonHelper.extractLongNamed(
|
final Long interestOnSavingsAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
|
||||||
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue())
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue())
|
||||||
@@ -326,11 +332,12 @@ public class SavingsProductDataValidator {
|
|||||||
baseDataValidator.reset().parameter(withdrawalFeeTypeParamName).value(withdrawalFeeType).ignoreIfNull()
|
baseDataValidator.reset().parameter(withdrawalFeeTypeParamName).value(withdrawalFeeType).ignoreIfNull()
|
||||||
.isOneOfTheseValues(1, 2);
|
.isOneOfTheseValues(1, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.fromApiJsonHelper.parameterExists(withdrawalFeeForTransfersParamName, element)) {
|
if (this.fromApiJsonHelper.parameterExists(withdrawalFeeForTransfersParamName, element)) {
|
||||||
final Boolean isWithdrawalFeeApplicableForTransfers = fromApiJsonHelper.extractBooleanNamed(withdrawalFeeForTransfersParamName, element);
|
final Boolean isWithdrawalFeeApplicableForTransfers = fromApiJsonHelper.extractBooleanNamed(withdrawalFeeForTransfersParamName,
|
||||||
baseDataValidator.reset().parameter(withdrawalFeeForTransfersParamName).value(isWithdrawalFeeApplicableForTransfers).ignoreIfNull()
|
element);
|
||||||
.validateForBooleanValue();
|
baseDataValidator.reset().parameter(withdrawalFeeForTransfersParamName).value(isWithdrawalFeeApplicableForTransfers)
|
||||||
|
.ignoreIfNull().validateForBooleanValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.fromApiJsonHelper.parameterExists(annualFeeAmountParamName, element)) {
|
if (this.fromApiJsonHelper.parameterExists(annualFeeAmountParamName, element)) {
|
||||||
@@ -353,6 +360,11 @@ public class SavingsProductDataValidator {
|
|||||||
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue())
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue())
|
||||||
.value(savingsReferenceAccountId).ignoreIfNull().integerGreaterThanZero();
|
.value(savingsReferenceAccountId).ignoreIfNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long transfersInSuspenseAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue())
|
||||||
|
.value(transfersInSuspenseAccountId).ignoreIfNull().integerGreaterThanZero();
|
||||||
|
|
||||||
final Long interestOnSavingsAccountId = fromApiJsonHelper.extractLongNamed(
|
final Long interestOnSavingsAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
|
||||||
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue())
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue())
|
||||||
|
|||||||
+15
-2
@@ -1178,7 +1178,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
return accountingBridgeData;
|
return accountingBridgeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<Long> findExistingTransactionIds() {
|
public Collection<Long> findExistingTransactionIds() {
|
||||||
|
|
||||||
final Collection<Long> ids = new ArrayList<Long>();
|
final Collection<Long> ids = new ArrayList<Long>();
|
||||||
|
|
||||||
@@ -1189,7 +1189,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<Long> findExistingReversedTransactionIds() {
|
public Collection<Long> findExistingReversedTransactionIds() {
|
||||||
|
|
||||||
final Collection<Long> ids = new ArrayList<Long>();
|
final Collection<Long> ids = new ArrayList<Long>();
|
||||||
|
|
||||||
@@ -1787,4 +1787,17 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
public LocalDate getClosedOnDate() {
|
public LocalDate getClosedOnDate() {
|
||||||
return (LocalDate) ObjectUtils.defaultIfNull(new LocalDate(this.closedOnDate), null);
|
return (LocalDate) ObjectUtils.defaultIfNull(new LocalDate(this.closedOnDate), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SavingsAccountSummary getSummary() {
|
||||||
|
return this.summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SavingsAccountTransaction> getTransactions() {
|
||||||
|
return this.transactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(Integer status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+20
@@ -14,6 +14,8 @@ public enum SavingsAccountStatusType {
|
|||||||
SUBMITTED_AND_PENDING_APPROVAL(100, "savingsAccountStatusType.submitted.and.pending.approval"), //
|
SUBMITTED_AND_PENDING_APPROVAL(100, "savingsAccountStatusType.submitted.and.pending.approval"), //
|
||||||
APPROVED(200, "savingsAccountStatusType.approved"), //
|
APPROVED(200, "savingsAccountStatusType.approved"), //
|
||||||
ACTIVE(300, "savingsAccountStatusType.active"), //
|
ACTIVE(300, "savingsAccountStatusType.active"), //
|
||||||
|
TRANSFER_IN_PROGRESS(303, "savingsAccountStatusType.transfer.in.progress"), //
|
||||||
|
TRANSFER_ON_HOLD(304, "savingsAccountStatusType.transfer.on.hold"), //
|
||||||
WITHDRAWN_BY_APPLICANT(400, "savingsAccountStatusType.withdrawn.by.applicant"), //
|
WITHDRAWN_BY_APPLICANT(400, "savingsAccountStatusType.withdrawn.by.applicant"), //
|
||||||
REJECTED(500, "savingsAccountStatusType.rejected"), //
|
REJECTED(500, "savingsAccountStatusType.rejected"), //
|
||||||
CLOSED(600, "savingsAccountStatusType.closed");
|
CLOSED(600, "savingsAccountStatusType.closed");
|
||||||
@@ -34,6 +36,12 @@ public enum SavingsAccountStatusType {
|
|||||||
case 300:
|
case 300:
|
||||||
enumeration = SavingsAccountStatusType.ACTIVE;
|
enumeration = SavingsAccountStatusType.ACTIVE;
|
||||||
break;
|
break;
|
||||||
|
case 303:
|
||||||
|
enumeration = SavingsAccountStatusType.TRANSFER_IN_PROGRESS;
|
||||||
|
break;
|
||||||
|
case 304:
|
||||||
|
enumeration = SavingsAccountStatusType.TRANSFER_ON_HOLD;
|
||||||
|
break;
|
||||||
case 400:
|
case 400:
|
||||||
enumeration = SavingsAccountStatusType.WITHDRAWN_BY_APPLICANT;
|
enumeration = SavingsAccountStatusType.WITHDRAWN_BY_APPLICANT;
|
||||||
break;
|
break;
|
||||||
@@ -87,4 +95,16 @@ public enum SavingsAccountStatusType {
|
|||||||
public boolean isClosed() {
|
public boolean isClosed() {
|
||||||
return this.value.equals(SavingsAccountStatusType.CLOSED.getValue()) || isRejected() || isApplicationWithdrawnByApplicant();
|
return this.value.equals(SavingsAccountStatusType.CLOSED.getValue()) || isRejected() || isApplicationWithdrawnByApplicant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isTransferInProgress() {
|
||||||
|
return this.value.equals(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTransferOnHold() {
|
||||||
|
return this.value.equals(SavingsAccountStatusType.TRANSFER_ON_HOLD.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUnderTransfer() {
|
||||||
|
return isTransferInProgress() || isTransferOnHold();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+5
@@ -79,4 +79,9 @@ public final class SavingsAccountSummary {
|
|||||||
public Money getAccountBalance(final MonetaryCurrency currency) {
|
public Money getAccountBalance(final MonetaryCurrency currency) {
|
||||||
return Money.of(currency, this.accountBalance);
|
return Money.of(currency, this.accountBalance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BigDecimal getAccountBalance() {
|
||||||
|
return this.accountBalance;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+30
-1
@@ -117,6 +117,30 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
|||||||
isReversed);
|
isReversed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SavingsAccountTransaction initiateTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date) {
|
||||||
|
final boolean isReversed = false;
|
||||||
|
final PaymentDetail paymentDetail = null;
|
||||||
|
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail,
|
||||||
|
SavingsAccountTransactionType.INITIATE_TRANSFER.getValue(), date, savingsAccount.getSummary().getAccountBalance(),
|
||||||
|
isReversed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SavingsAccountTransaction approveTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date) {
|
||||||
|
final boolean isReversed = false;
|
||||||
|
final PaymentDetail paymentDetail = null;
|
||||||
|
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail,
|
||||||
|
SavingsAccountTransactionType.APPROVE_TRANSFER.getValue(), date, savingsAccount.getSummary().getAccountBalance(),
|
||||||
|
isReversed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SavingsAccountTransaction withdrawTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date) {
|
||||||
|
final boolean isReversed = false;
|
||||||
|
final PaymentDetail paymentDetail = null;
|
||||||
|
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail,
|
||||||
|
SavingsAccountTransactionType.WITHDRAW_TRANSFER.getValue(), date, savingsAccount.getSummary().getAccountBalance(),
|
||||||
|
isReversed);
|
||||||
|
}
|
||||||
|
|
||||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final Integer typeOf,
|
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final Integer typeOf,
|
||||||
final LocalDate transactionLocalDate, final Money amount, final boolean isReversed) {
|
final LocalDate transactionLocalDate, final Money amount, final boolean isReversed) {
|
||||||
this(savingsAccount, office, null, typeOf, transactionLocalDate, amount, isReversed);
|
this(savingsAccount, office, null, typeOf, transactionLocalDate, amount, isReversed);
|
||||||
@@ -124,11 +148,16 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail,
|
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail,
|
||||||
final Integer typeOf, final LocalDate transactionLocalDate, final Money amount, final boolean isReversed) {
|
final Integer typeOf, final LocalDate transactionLocalDate, final Money amount, final boolean isReversed) {
|
||||||
|
this(savingsAccount, office, paymentDetail, typeOf, transactionLocalDate, amount.getAmount(), isReversed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail,
|
||||||
|
final Integer typeOf, final LocalDate transactionLocalDate, final BigDecimal amount, final boolean isReversed) {
|
||||||
this.savingsAccount = savingsAccount;
|
this.savingsAccount = savingsAccount;
|
||||||
this.office = office;
|
this.office = office;
|
||||||
this.typeOf = typeOf;
|
this.typeOf = typeOf;
|
||||||
this.dateOf = transactionLocalDate.toDate();
|
this.dateOf = transactionLocalDate.toDate();
|
||||||
this.amount = amount.getAmount();
|
this.amount = amount;
|
||||||
this.reversed = isReversed;
|
this.reversed = isReversed;
|
||||||
this.paymentDetail = paymentDetail;
|
this.paymentDetail = paymentDetail;
|
||||||
|
|
||||||
|
|||||||
+12
-1
@@ -8,6 +8,9 @@ package org.mifosplatform.portfolio.savings.service;
|
|||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.mifosplatform.organisation.office.domain.Office;
|
||||||
|
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||||
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransaction;
|
||||||
|
|
||||||
public interface SavingsAccountWritePlatformService {
|
public interface SavingsAccountWritePlatformService {
|
||||||
|
|
||||||
@@ -28,6 +31,14 @@ public interface SavingsAccountWritePlatformService {
|
|||||||
void postInterestForAccounts();
|
void postInterestForAccounts();
|
||||||
|
|
||||||
CommandProcessingResult adjustSavingsTransaction(Long savingsId, Long transactionId, JsonCommand command);
|
CommandProcessingResult adjustSavingsTransaction(Long savingsId, Long transactionId, JsonCommand command);
|
||||||
|
|
||||||
CommandProcessingResult close(Long savingsId, JsonCommand command);
|
CommandProcessingResult close(Long savingsId, JsonCommand command);
|
||||||
|
|
||||||
|
SavingsAccountTransaction initiateSavingsTransfer(Long accountId, LocalDate transferDate);
|
||||||
|
|
||||||
|
SavingsAccountTransaction withdrawSavingsTransfer(Long accountId, LocalDate transferDate);
|
||||||
|
|
||||||
|
void rejectSavingsTransfer(Long accountId);
|
||||||
|
|
||||||
|
SavingsAccountTransaction acceptSavingsTransfer(Long accountId, LocalDate transferDate, Office acceptedInOffice, Staff staff);
|
||||||
}
|
}
|
||||||
+85
-12
@@ -34,6 +34,8 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
|
|||||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
||||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
|
import org.mifosplatform.organisation.office.domain.Office;
|
||||||
|
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||||
import org.mifosplatform.portfolio.client.domain.Client;
|
import org.mifosplatform.portfolio.client.domain.Client;
|
||||||
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
|
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
|
||||||
import org.mifosplatform.portfolio.group.domain.Group;
|
import org.mifosplatform.portfolio.group.domain.Group;
|
||||||
@@ -304,7 +306,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
final MathContext mc = new MathContext(15, RoundingMode.HALF_EVEN);
|
final MathContext mc = new MathContext(15, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
||||||
if(account.isNotActive()){
|
if (account.isNotActive()) {
|
||||||
throwValidationForActiveStatus(SavingsApiConstants.undoTransactionAction);
|
throwValidationForActiveStatus(SavingsApiConstants.undoTransactionAction);
|
||||||
}
|
}
|
||||||
account.undoTransaction(transactionId, reversedTransactionIds);
|
account.undoTransaction(transactionId, reversedTransactionIds);
|
||||||
@@ -342,7 +344,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
|
|
||||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
||||||
if(account.isNotActive()){
|
if (account.isNotActive()) {
|
||||||
throwValidationForActiveStatus(SavingsApiConstants.adjustTransactionAction);
|
throwValidationForActiveStatus(SavingsApiConstants.adjustTransactionAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,23 +359,23 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
|
|
||||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
||||||
account.undoTransaction(transactionId, existingReversedTransactionIds);
|
account.undoTransaction(transactionId, existingReversedTransactionIds);
|
||||||
|
|
||||||
//for undo withdrawal fee
|
// for undo withdrawal fee
|
||||||
SavingsAccountTransaction nextSavingsAccountTransaction = this.savingsAccountTransactionRepository.findOneByIdAndSavingsAccountId(
|
SavingsAccountTransaction nextSavingsAccountTransaction = this.savingsAccountTransactionRepository.findOneByIdAndSavingsAccountId(
|
||||||
transactionId+1, savingsId);
|
transactionId + 1, savingsId);
|
||||||
if(nextSavingsAccountTransaction.isWithdrawalFeeAndNotReversed()){
|
if (nextSavingsAccountTransaction.isWithdrawalFeeAndNotReversed()) {
|
||||||
account.undoTransaction(transactionId+1, existingReversedTransactionIds);
|
account.undoTransaction(transactionId + 1, existingReversedTransactionIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
SavingsAccountTransaction transaction = null;
|
SavingsAccountTransaction transaction = null;
|
||||||
if (savingsAccountTransaction.isDeposit()) {
|
if (savingsAccountTransaction.isDeposit()) {
|
||||||
SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||||
existingTransactionIds, existingReversedTransactionIds,paymentDetail);
|
existingTransactionIds, existingReversedTransactionIds, paymentDetail);
|
||||||
transaction = account.deposit(transactionDTO);
|
transaction = account.deposit(transactionDTO);
|
||||||
} else {
|
} else {
|
||||||
SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||||
existingTransactionIds, existingReversedTransactionIds, paymentDetail);
|
existingTransactionIds, existingReversedTransactionIds, paymentDetail);
|
||||||
transaction = account.withdraw(transactionDTO , true);
|
transaction = account.withdraw(transactionDTO, true);
|
||||||
}
|
}
|
||||||
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
|
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
|
||||||
|
|
||||||
@@ -455,4 +457,75 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
.with(changes) //
|
.with(changes) //
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SavingsAccountTransaction initiateSavingsTransfer(Long accountId, LocalDate transferDate) {
|
||||||
|
final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(accountId);
|
||||||
|
|
||||||
|
final List<Long> existingTransactionIds = new ArrayList<Long>(savingsAccount.findExistingTransactionIds());
|
||||||
|
final List<Long> existingReversedTransactionIds = new ArrayList<Long>(savingsAccount.findExistingReversedTransactionIds());
|
||||||
|
|
||||||
|
final SavingsAccountTransaction newTransferTransaction = SavingsAccountTransaction.initiateTransfer(savingsAccount,
|
||||||
|
savingsAccount.office(), transferDate);
|
||||||
|
savingsAccount.getTransactions().add(newTransferTransaction);
|
||||||
|
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
|
||||||
|
|
||||||
|
this.savingsAccountTransactionRepository.save(newTransferTransaction);
|
||||||
|
this.savingAccountRepository.save(savingsAccount);
|
||||||
|
|
||||||
|
postJournalEntries(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
|
return newTransferTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SavingsAccountTransaction withdrawSavingsTransfer(Long accountId, LocalDate transferDate) {
|
||||||
|
final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(accountId);
|
||||||
|
|
||||||
|
final List<Long> existingTransactionIds = new ArrayList<Long>(savingsAccount.findExistingTransactionIds());
|
||||||
|
final List<Long> existingReversedTransactionIds = new ArrayList<Long>(savingsAccount.findExistingReversedTransactionIds());
|
||||||
|
|
||||||
|
final SavingsAccountTransaction withdrawtransferTransaction = SavingsAccountTransaction.withdrawTransfer(savingsAccount,
|
||||||
|
savingsAccount.office(), transferDate);
|
||||||
|
savingsAccount.getTransactions().add(withdrawtransferTransaction);
|
||||||
|
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||||
|
|
||||||
|
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
|
||||||
|
this.savingAccountRepository.save(savingsAccount);
|
||||||
|
|
||||||
|
postJournalEntries(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
|
return withdrawtransferTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rejectSavingsTransfer(Long accountId) {
|
||||||
|
final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(accountId);
|
||||||
|
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_ON_HOLD.getValue());
|
||||||
|
this.savingAccountRepository.save(savingsAccount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SavingsAccountTransaction acceptSavingsTransfer(Long accountId, LocalDate transferDate, Office acceptedInOffice,
|
||||||
|
Staff fieldOfficer) {
|
||||||
|
final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(accountId);
|
||||||
|
|
||||||
|
final List<Long> existingTransactionIds = new ArrayList<Long>(savingsAccount.findExistingTransactionIds());
|
||||||
|
final List<Long> existingReversedTransactionIds = new ArrayList<Long>(savingsAccount.findExistingReversedTransactionIds());
|
||||||
|
|
||||||
|
final SavingsAccountTransaction acceptTransferTransaction = SavingsAccountTransaction.approveTransfer(savingsAccount,
|
||||||
|
acceptedInOffice, transferDate);
|
||||||
|
savingsAccount.getTransactions().add(acceptTransferTransaction);
|
||||||
|
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||||
|
if (fieldOfficer != null) {
|
||||||
|
savingsAccount.update(fieldOfficer);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
|
||||||
|
this.savingAccountRepository.save(savingsAccount);
|
||||||
|
|
||||||
|
postJournalEntries(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
|
return acceptTransferTransaction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+23
-8
@@ -100,46 +100,61 @@ public class SavingsEnumerations {
|
|||||||
final boolean isWithdrawnByApplicant = type.isApplicationWithdrawnByApplicant();
|
final boolean isWithdrawnByApplicant = type.isApplicationWithdrawnByApplicant();
|
||||||
final boolean isActive = type.isActive();
|
final boolean isActive = type.isActive();
|
||||||
final boolean isClosed = type.isClosed();
|
final boolean isClosed = type.isClosed();
|
||||||
|
final boolean isTransferInProgress = type.isTransferInProgress();
|
||||||
|
final boolean isTransferOnHold = type.isTransferOnHold();
|
||||||
|
|
||||||
SavingsAccountStatusEnumData optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.INVALID.getValue().longValue(),
|
SavingsAccountStatusEnumData optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.INVALID.getValue().longValue(),
|
||||||
SavingsAccountStatusType.INVALID.getCode(), "Invalid", submittedAndPendingApproval, isApproved, isRejected,
|
SavingsAccountStatusType.INVALID.getCode(), "Invalid", submittedAndPendingApproval, isApproved, isRejected,
|
||||||
isWithdrawnByApplicant, isActive, isClosed);
|
isWithdrawnByApplicant, isActive, isClosed, isTransferInProgress, isTransferOnHold);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case INVALID:
|
case INVALID:
|
||||||
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.INVALID.getValue().longValue(),
|
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.INVALID.getValue().longValue(),
|
||||||
SavingsAccountStatusType.INVALID.getCode(), "Invalid", submittedAndPendingApproval, isApproved, isRejected,
|
SavingsAccountStatusType.INVALID.getCode(), "Invalid", submittedAndPendingApproval, isApproved, isRejected,
|
||||||
isWithdrawnByApplicant, isActive, isClosed);
|
isWithdrawnByApplicant, isActive, isClosed, isTransferInProgress, isTransferOnHold);
|
||||||
break;
|
break;
|
||||||
case SUBMITTED_AND_PENDING_APPROVAL:
|
case SUBMITTED_AND_PENDING_APPROVAL:
|
||||||
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL.getValue()
|
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL.getValue()
|
||||||
.longValue(), SavingsAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL.getCode(), "Submitted and pending approval",
|
.longValue(), SavingsAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL.getCode(), "Submitted and pending approval",
|
||||||
submittedAndPendingApproval, isApproved, isRejected, isWithdrawnByApplicant, isActive, isClosed);
|
submittedAndPendingApproval, isApproved, isRejected, isWithdrawnByApplicant, isActive, isClosed,
|
||||||
|
isTransferInProgress, isTransferOnHold);
|
||||||
break;
|
break;
|
||||||
case REJECTED:
|
case REJECTED:
|
||||||
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.REJECTED.getValue().longValue(),
|
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.REJECTED.getValue().longValue(),
|
||||||
SavingsAccountStatusType.REJECTED.getCode(), "Rejected", submittedAndPendingApproval, isApproved, isRejected,
|
SavingsAccountStatusType.REJECTED.getCode(), "Rejected", submittedAndPendingApproval, isApproved, isRejected,
|
||||||
isWithdrawnByApplicant, isActive, isClosed);
|
isWithdrawnByApplicant, isActive, isClosed, isTransferInProgress, isTransferOnHold);
|
||||||
break;
|
break;
|
||||||
case WITHDRAWN_BY_APPLICANT:
|
case WITHDRAWN_BY_APPLICANT:
|
||||||
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.WITHDRAWN_BY_APPLICANT.getValue().longValue(),
|
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.WITHDRAWN_BY_APPLICANT.getValue().longValue(),
|
||||||
SavingsAccountStatusType.WITHDRAWN_BY_APPLICANT.getCode(), "Withdrawn by applicant", submittedAndPendingApproval,
|
SavingsAccountStatusType.WITHDRAWN_BY_APPLICANT.getCode(), "Withdrawn by applicant", submittedAndPendingApproval,
|
||||||
isApproved, isRejected, isWithdrawnByApplicant, isActive, isClosed);
|
isApproved, isRejected, isWithdrawnByApplicant, isActive, isClosed, isTransferInProgress, isTransferOnHold);
|
||||||
break;
|
break;
|
||||||
case APPROVED:
|
case APPROVED:
|
||||||
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.APPROVED.getValue().longValue(),
|
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.APPROVED.getValue().longValue(),
|
||||||
SavingsAccountStatusType.APPROVED.getCode(), "Approved", submittedAndPendingApproval, isApproved, isRejected,
|
SavingsAccountStatusType.APPROVED.getCode(), "Approved", submittedAndPendingApproval, isApproved, isRejected,
|
||||||
isWithdrawnByApplicant, isActive, isClosed);
|
isWithdrawnByApplicant, isActive, isClosed, isTransferInProgress, isTransferOnHold);
|
||||||
break;
|
break;
|
||||||
case ACTIVE:
|
case ACTIVE:
|
||||||
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.ACTIVE.getValue().longValue(),
|
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.ACTIVE.getValue().longValue(),
|
||||||
SavingsAccountStatusType.ACTIVE.getCode(), "Active", submittedAndPendingApproval, isApproved, isRejected,
|
SavingsAccountStatusType.ACTIVE.getCode(), "Active", submittedAndPendingApproval, isApproved, isRejected,
|
||||||
isWithdrawnByApplicant, isActive, isClosed);
|
isWithdrawnByApplicant, isActive, isClosed, isTransferInProgress, isTransferOnHold);
|
||||||
break;
|
break;
|
||||||
case CLOSED:
|
case CLOSED:
|
||||||
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.CLOSED.getValue().longValue(),
|
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.CLOSED.getValue().longValue(),
|
||||||
SavingsAccountStatusType.CLOSED.getCode(), "Closed", submittedAndPendingApproval, isApproved, isRejected,
|
SavingsAccountStatusType.CLOSED.getCode(), "Closed", submittedAndPendingApproval, isApproved, isRejected,
|
||||||
isWithdrawnByApplicant, isActive, isClosed);
|
isWithdrawnByApplicant, isActive, isClosed, isTransferInProgress, isTransferOnHold);
|
||||||
|
break;
|
||||||
|
case TRANSFER_IN_PROGRESS:
|
||||||
|
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue().longValue(),
|
||||||
|
SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getCode(), "Transfer in progress", submittedAndPendingApproval,
|
||||||
|
isApproved, isRejected, isWithdrawnByApplicant, isActive, isClosed, isTransferInProgress, isTransferOnHold);
|
||||||
|
break;
|
||||||
|
case TRANSFER_ON_HOLD:
|
||||||
|
optionData = new SavingsAccountStatusEnumData(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue().longValue(),
|
||||||
|
SavingsAccountStatusType.TRANSFER_ON_HOLD.getCode(), "Transfer in progress", submittedAndPendingApproval,
|
||||||
|
isApproved, isRejected, isWithdrawnByApplicant, isActive, isClosed, isTransferInProgress, isTransferOnHold);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return optionData;
|
return optionData;
|
||||||
|
|||||||
+30
-3
@@ -35,7 +35,9 @@ import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
|||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
|
||||||
import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService;
|
import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||||
import org.mifosplatform.portfolio.note.service.NoteWritePlatformService;
|
import org.mifosplatform.portfolio.note.service.NoteWritePlatformService;
|
||||||
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
|
||||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountRepository;
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountRepository;
|
||||||
|
import org.mifosplatform.portfolio.savings.service.SavingsAccountWritePlatformService;
|
||||||
import org.mifosplatform.portfolio.transfer.api.TransferApiConstants;
|
import org.mifosplatform.portfolio.transfer.api.TransferApiConstants;
|
||||||
import org.mifosplatform.portfolio.transfer.data.TransfersDataValidator;
|
import org.mifosplatform.portfolio.transfer.data.TransfersDataValidator;
|
||||||
import org.mifosplatform.portfolio.transfer.exception.ClientNotAwaitingTransferApprovalException;
|
import org.mifosplatform.portfolio.transfer.exception.ClientNotAwaitingTransferApprovalException;
|
||||||
@@ -58,6 +60,7 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
|||||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||||
private final GroupRepositoryWrapper groupRepository;
|
private final GroupRepositoryWrapper groupRepository;
|
||||||
private final LoanWritePlatformService loanWritePlatformService;
|
private final LoanWritePlatformService loanWritePlatformService;
|
||||||
|
private final SavingsAccountWritePlatformService savingsAccountWritePlatformService;
|
||||||
private final LoanRepository loanRepository;
|
private final LoanRepository loanRepository;
|
||||||
private final SavingsAccountRepository savingsAccountRepository;
|
private final SavingsAccountRepository savingsAccountRepository;
|
||||||
private final TransfersDataValidator transfersDataValidator;
|
private final TransfersDataValidator transfersDataValidator;
|
||||||
@@ -70,7 +73,8 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
|||||||
final LoanWritePlatformService loanWritePlatformService, final GroupRepositoryWrapper groupRepository,
|
final LoanWritePlatformService loanWritePlatformService, final GroupRepositoryWrapper groupRepository,
|
||||||
final LoanRepository loanRepository, final TransfersDataValidator transfersDataValidator,
|
final LoanRepository loanRepository, final TransfersDataValidator transfersDataValidator,
|
||||||
final NoteWritePlatformService noteWritePlatformService, final StaffRepositoryWrapper staffRepositoryWrapper,
|
final NoteWritePlatformService noteWritePlatformService, final StaffRepositoryWrapper staffRepositoryWrapper,
|
||||||
final SavingsAccountRepository savingsAccountRepository) {
|
final SavingsAccountRepository savingsAccountRepository,
|
||||||
|
final SavingsAccountWritePlatformService savingsAccountWritePlatformService) {
|
||||||
this.clientRepository = clientRepository;
|
this.clientRepository = clientRepository;
|
||||||
this.officeRepository = officeRepository;
|
this.officeRepository = officeRepository;
|
||||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||||
@@ -81,6 +85,7 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
|||||||
this.noteWritePlatformService = noteWritePlatformService;
|
this.noteWritePlatformService = noteWritePlatformService;
|
||||||
this.staffRepositoryWrapper = staffRepositoryWrapper;
|
this.staffRepositoryWrapper = staffRepositoryWrapper;
|
||||||
this.savingsAccountRepository = savingsAccountRepository;
|
this.savingsAccountRepository = savingsAccountRepository;
|
||||||
|
this.savingsAccountWritePlatformService = savingsAccountWritePlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -345,8 +350,30 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*** Handle Active Savings (Currently throw and exception) ***/
|
/*** Handle Active Savings (Currently throw and exception) ***/
|
||||||
if (savingsAccountRepository.doNonClosedSavingAccountsExistForClient(client.getId())) { throw new TransferNotSupportedException(
|
if (savingsAccountRepository.doNonClosedSavingAccountsExistForClient(client.getId())) {
|
||||||
TRANSFER_NOT_SUPPORTED_REASON.ACTIVE_SAVINGS_ACCOUNT, client.getId()); }
|
// get each individual saving account for the client
|
||||||
|
for (SavingsAccount savingsAccount : savingsAccountRepository.findSavingAccountByClientId(client.getId())) {
|
||||||
|
if (!savingsAccount.isClosed()) {
|
||||||
|
switch (transferEventType) {
|
||||||
|
case ACCEPTANCE:
|
||||||
|
this.savingsAccountWritePlatformService.acceptSavingsTransfer(savingsAccount.getId(),
|
||||||
|
DateUtils.getLocalDateOfTenant(), destinationOffice, staff);
|
||||||
|
break;
|
||||||
|
case PROPOSAL:
|
||||||
|
this.savingsAccountWritePlatformService.initiateSavingsTransfer(savingsAccount.getId(),
|
||||||
|
DateUtils.getLocalDateOfTenant());
|
||||||
|
break;
|
||||||
|
case REJECTION:
|
||||||
|
this.savingsAccountWritePlatformService.withdrawSavingsTransfer(savingsAccount.getId(),
|
||||||
|
DateUtils.getLocalDateOfTenant());
|
||||||
|
break;
|
||||||
|
case WITHDRAWAL:
|
||||||
|
this.savingsAccountWritePlatformService.withdrawSavingsTransfer(savingsAccount.getId(),
|
||||||
|
DateUtils.getLocalDateOfTenant());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (transferEventType) {
|
switch (transferEventType) {
|
||||||
case ACCEPTANCE:
|
case ACCEPTANCE:
|
||||||
|
|||||||
Reference in New Issue
Block a user