FINERACT-1960: GL account mappings to use Savings product with Accrual accounting

This commit is contained in:
Jose Alberto Hernandez
2024-02-26 15:25:28 +01:00
committed by Adam Saghy
parent 051b37c4b3
commit 6ee881b89a
29 changed files with 1278 additions and 796 deletions
@@ -40,6 +40,9 @@ public class AccountingProcessorForSavingsFactory {
if (savingsDTO.isCashBasedAccountingEnabled()) {
accountingProcessorForSavings = this.applicationContext.getBean("cashBasedAccountingProcessorForSavings",
AccountingProcessorForSavings.class);
} else if (savingsDTO.isAccrualBasedAccountingEnabled()) {
accountingProcessorForSavings = this.applicationContext.getBean("accrualBasedAccountingProcessorForSavings",
AccountingProcessorForSavings.class);
}
return accountingProcessorForSavings;
@@ -30,6 +30,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.accounting.closure.domain.GLClosure;
import org.apache.fineract.accounting.closure.domain.GLClosureRepository;
import org.apache.fineract.accounting.common.AccountingConstants.AccrualAccountsForLoan;
import org.apache.fineract.accounting.common.AccountingConstants.AccrualAccountsForSavings;
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForLoan;
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForSavings;
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForShares;
@@ -573,6 +574,28 @@ public class AccountingProcessorHelper {
paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
}
public void createAccrualBasedJournalEntriesAndReversalsForSavingsTax(final Office office, final String currencyCode,
final AccrualAccountsForSavings accountTypeToBeDebited, final AccrualAccountsForSavings accountTypeToBeCredited,
final Long savingsProductId, final Long paymentTypeId, final Long savingsId, final String transactionId,
final LocalDate transactionDate, final BigDecimal amount, final Boolean isReversal, final List<TaxPaymentDTO> taxDetails) {
for (TaxPaymentDTO taxPaymentDTO : taxDetails) {
if (taxPaymentDTO.getAmount() != null) {
if (taxPaymentDTO.getCreditAccountId() == null) {
createAccrualBasedCreditJournalEntriesAndReversalsForSavings(office, currencyCode, accountTypeToBeCredited.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, taxPaymentDTO.getAmount(),
isReversal);
} else {
createAccrualBasedBasedCreditJournalEntriesAndReversalsForSavings(office, currencyCode,
taxPaymentDTO.getCreditAccountId(), savingsId, transactionId, transactionDate, taxPaymentDTO.getAmount(),
isReversal);
}
}
}
createAccrualBasedDebitJournalEntriesAndReversalsForSavings(office, currencyCode, accountTypeToBeDebited.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
}
public void createCashBasedDebitJournalEntriesAndReversalsForSavings(final Office office, final String currencyCode,
final Integer accountTypeToBeDebited, final Long savingsProductId, final Long paymentTypeId, final Long savingsId,
final String transactionId, final LocalDate transactionDate, final BigDecimal amount, final Boolean isReversal) {
@@ -623,6 +646,56 @@ public class AccountingProcessorHelper {
}
}
public void createAccrualBasedDebitJournalEntriesAndReversalsForSavings(final Office office, final String currencyCode,
final Integer accountTypeToBeDebited, final Long savingsProductId, final Long paymentTypeId, final Long savingsId,
final String transactionId, final LocalDate transactionDate, final BigDecimal amount, final Boolean isReversal) {
// reverse debits and credits for reversals
if (isReversal) {
createCreditJournalEntriesForSavings(office, currencyCode, accountTypeToBeDebited, savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, amount);
} else {
createDebitJournalEntriesForSavings(office, currencyCode, accountTypeToBeDebited, savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, amount);
}
}
public void createAccrualBasedCreditJournalEntriesAndReversalsForSavings(final Office office, final String currencyCode,
final Integer accountTypeToBeCredited, final Long savingsProductId, final Long paymentTypeId, final Long savingsId,
final String transactionId, final LocalDate transactionDate, final BigDecimal amount, final Boolean isReversal) {
// reverse debits and credits for reversals
if (isReversal) {
createDebitJournalEntriesForSavings(office, currencyCode, accountTypeToBeCredited, savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, amount);
} else {
createCreditJournalEntriesForSavings(office, currencyCode, accountTypeToBeCredited, savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, amount);
}
}
public void createAccrualBasedDebitJournalEntriesAndReversalsForSavings(final Office office, final String currencyCode,
final Long debitAccountId, final Long savingsId, final String transactionId, final LocalDate transactionDate,
final BigDecimal amount, final Boolean isReversal) {
// reverse debits and credits for reversals
final GLAccount debitAccount = getGLAccountById(debitAccountId);
if (isReversal) {
createCreditJournalEntryForSavings(office, currencyCode, debitAccount, savingsId, transactionId, transactionDate, amount);
} else {
createDebitJournalEntryForSavings(office, currencyCode, debitAccount, savingsId, transactionId, transactionDate, amount);
}
}
public void createAccrualBasedBasedCreditJournalEntriesAndReversalsForSavings(final Office office, final String currencyCode,
final Long creditAccountId, final Long savingsId, final String transactionId, final LocalDate transactionDate,
final BigDecimal amount, final Boolean isReversal) {
// reverse debits and credits for reversals
final GLAccount creditAccount = getGLAccountById(creditAccountId);
if (isReversal) {
createDebitJournalEntryForSavings(office, currencyCode, creditAccount, savingsId, transactionId, transactionDate, amount);
} else {
createCreditJournalEntryForSavings(office, currencyCode, creditAccount, savingsId, transactionId, transactionDate, amount);
}
}
private void createDebitJournalEntriesForSavings(final Office office, final String currencyCode, final int accountTypeToDebitId,
final Long savingsProductId, final Long paymentTypeId, final Long savingsId, final String transactionId,
final LocalDate transactionDate, final BigDecimal amount) {
@@ -768,6 +841,41 @@ public class AccountingProcessorHelper {
}
}
public void createAccrualBasedJournalEntriesAndReversalsForSavingsCharges(final Office office, final String currencyCode,
final AccrualAccountsForSavings accountTypeToBeDebited, AccrualAccountsForSavings accountTypeToBeCredited,
final Long savingsProductId, final Long paymentTypeId, final Long loanId, final String transactionId,
final LocalDate transactionDate, final BigDecimal totalAmount, final Boolean isReversal,
final List<ChargePaymentDTO> chargePaymentDTOs) {
// TODO Vishwas: Remove this validation, as and when appropriate Junit
// tests are written for accounting
/**
* Accounting module currently supports a single charge per transaction, throw an error if this is not the case
* here so any developers changing the expected portfolio behavior would also take care of modifying the
* accounting code appropriately
**/
if (chargePaymentDTOs.size() != 1) {
throw new PlatformDataIntegrityException("Recent Portfolio changes w.r.t Charges for Savings have Broken the accounting code",
"Recent Portfolio changes w.r.t Charges for Savings have Broken the accounting code");
}
ChargePaymentDTO chargePaymentDTO = chargePaymentDTOs.get(0);
GLAccount chargeSpecificAccount = getLinkedGLAccountForSavingsCharges(savingsProductId, accountTypeToBeCredited.getValue(),
chargePaymentDTO.getChargeId());
final GLAccount savingsControlAccount = getLinkedGLAccountForSavingsProduct(savingsProductId, accountTypeToBeDebited.getValue(),
paymentTypeId);
if (isReversal) {
createDebitJournalEntryForSavings(office, currencyCode, chargeSpecificAccount, loanId, transactionId, transactionDate,
totalAmount);
createCreditJournalEntryForSavings(office, currencyCode, savingsControlAccount, loanId, transactionId, transactionDate,
totalAmount);
} else {
createDebitJournalEntryForSavings(office, currencyCode, savingsControlAccount, loanId, transactionId, transactionDate,
totalAmount);
createCreditJournalEntryForSavings(office, currencyCode, chargeSpecificAccount, loanId, transactionId, transactionDate,
totalAmount);
}
}
public LoanTransaction getLoanTransactionById(final Long loanTransactionId) {
return this.loanTransactionRepository.getReferenceById(loanTransactionId);
}
@@ -0,0 +1,272 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.accounting.journalentry.service;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.accounting.closure.domain.GLClosure;
import org.apache.fineract.accounting.common.AccountingConstants.AccrualAccountsForSavings;
import org.apache.fineract.accounting.common.AccountingConstants.FinancialActivity;
import org.apache.fineract.accounting.journalentry.data.ChargePaymentDTO;
import org.apache.fineract.accounting.journalentry.data.SavingsDTO;
import org.apache.fineract.accounting.journalentry.data.SavingsTransactionDTO;
import org.apache.fineract.organisation.office.domain.Office;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class AccrualBasedAccountingProcessorForSavings implements AccountingProcessorForSavings {
private final AccountingProcessorHelper helper;
@Override
public void createJournalEntriesForSavings(final SavingsDTO savingsDTO) {
final GLClosure latestGLClosure = this.helper.getLatestClosureByBranch(savingsDTO.getOfficeId());
final Long savingsProductId = savingsDTO.getSavingsProductId();
final Long savingsId = savingsDTO.getSavingsId();
final String currencyCode = savingsDTO.getCurrencyCode();
for (final SavingsTransactionDTO savingsTransactionDTO : savingsDTO.getNewSavingsTransactions()) {
final LocalDate transactionDate = savingsTransactionDTO.getTransactionDate();
final String transactionId = savingsTransactionDTO.getTransactionId();
final Office office = this.helper.getOfficeById(savingsTransactionDTO.getOfficeId());
final Long paymentTypeId = savingsTransactionDTO.getPaymentTypeId();
final boolean isReversal = savingsTransactionDTO.isReversed();
final BigDecimal amount = savingsTransactionDTO.getAmount();
final BigDecimal overdraftAmount = savingsTransactionDTO.getOverdraftAmount();
final List<ChargePaymentDTO> feePayments = savingsTransactionDTO.getFeePayments();
final List<ChargePaymentDTO> penaltyPayments = savingsTransactionDTO.getPenaltyPayments();
this.helper.checkForBranchClosures(latestGLClosure, transactionDate);
if (savingsTransactionDTO.getTransactionType().isWithdrawal() && savingsTransactionDTO.isOverdraftTransaction()) {
boolean isPositive = amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0;
if (savingsTransactionDTO.isAccountTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
FinancialActivity.LIABILITY_TRANSFER.getValue(), savingsProductId, paymentTypeId, savingsId, transactionId,
transactionDate, overdraftAmount, isReversal);
if (isPositive) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(), FinancialActivity.LIABILITY_TRANSFER.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate,
amount.subtract(overdraftAmount), isReversal);
}
} else {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
AccrualAccountsForSavings.SAVINGS_REFERENCE.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, overdraftAmount, isReversal);
if (isPositive) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(),
AccrualAccountsForSavings.SAVINGS_REFERENCE.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, amount.subtract(overdraftAmount), isReversal);
}
}
}
else if (savingsTransactionDTO.getTransactionType().isDeposit() && savingsTransactionDTO.isOverdraftTransaction()) {
boolean isPositive = amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0;
if (savingsTransactionDTO.isAccountTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
FinancialActivity.LIABILITY_TRANSFER.getValue(),
AccrualAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, overdraftAmount, isReversal);
if (isPositive) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
FinancialActivity.LIABILITY_TRANSFER.getValue(), AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate,
amount.subtract(overdraftAmount), isReversal);
}
} else {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_REFERENCE.getValue(),
AccrualAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, overdraftAmount, isReversal);
if (isPositive) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_REFERENCE.getValue(),
AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, amount.subtract(overdraftAmount), isReversal);
}
}
}
/** Handle Deposits and reversals of deposits **/
else if (savingsTransactionDTO.getTransactionType().isDeposit()) {
if (savingsTransactionDTO.isAccountTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
FinancialActivity.LIABILITY_TRANSFER.getValue(), AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
} else {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_REFERENCE.getValue(), AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
}
}
/** Handle Deposits and reversals of Dividend pay outs **/
else if (savingsTransactionDTO.getTransactionType().isDividendPayout()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
FinancialActivity.PAYABLE_DIVIDENDS.getValue(), AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
}
/** Handle withdrawals and reversals of withdrawals **/
else if (savingsTransactionDTO.getTransactionType().isWithdrawal()) {
if (savingsTransactionDTO.isAccountTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(), FinancialActivity.LIABILITY_TRANSFER.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
} else {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(), AccrualAccountsForSavings.SAVINGS_REFERENCE.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
}
}
else if (savingsTransactionDTO.getTransactionType().isEscheat()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(), AccrualAccountsForSavings.ESCHEAT_LIABILITY.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
}
/**
* Handle Interest Applications and reversals of Interest Applications
**/
else if (savingsTransactionDTO.getTransactionType().isInterestPosting() && savingsTransactionDTO.isOverdraftTransaction()) {
boolean isPositive = amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0;
// Post journal entry if earned interest amount is greater than
// zero
if (savingsTransactionDTO.getAmount().compareTo(BigDecimal.ZERO) > 0) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.INTEREST_ON_SAVINGS.getValue(),
AccrualAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, overdraftAmount, isReversal);
if (isPositive) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.INTEREST_ON_SAVINGS.getValue(),
AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, amount.subtract(overdraftAmount), isReversal);
}
}
}
else if (savingsTransactionDTO.getTransactionType().isInterestPosting()) {
// Post journal entry if earned interest amount is greater than
// zero
if (savingsTransactionDTO.getAmount().compareTo(BigDecimal.ZERO) > 0) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.INTEREST_PAYABLE.getValue(), AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
}
}
else if (savingsTransactionDTO.getTransactionType().isAccrual()) {
// Post journal entry for Accrual Recognition
if (savingsTransactionDTO.getAmount().compareTo(BigDecimal.ZERO) > 0) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.INTEREST_ON_SAVINGS.getValue(), AccrualAccountsForSavings.INTEREST_PAYABLE.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
}
}
else if (savingsTransactionDTO.getTransactionType().isWithholdTax()) {
this.helper.createAccrualBasedJournalEntriesAndReversalsForSavingsTax(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_CONTROL, AccrualAccountsForSavings.SAVINGS_REFERENCE, savingsProductId,
paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal,
savingsTransactionDTO.getTaxPayments());
}
/** Handle Fees Deductions and reversals of Fees Deductions **/
else if (savingsTransactionDTO.getTransactionType().isFeeDeduction() && savingsTransactionDTO.isOverdraftTransaction()) {
boolean isPositive = amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0;
// Is the Charge a penalty?
if (penaltyPayments.size() > 0) {
this.helper.createAccrualBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
AccrualAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL, AccrualAccountsForSavings.INCOME_FROM_PENALTIES,
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, overdraftAmount, isReversal,
penaltyPayments);
if (isPositive) {
this.helper.createAccrualBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_CONTROL, AccrualAccountsForSavings.INCOME_FROM_PENALTIES,
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate,
amount.subtract(overdraftAmount), isReversal, penaltyPayments);
}
} else {
this.helper.createAccrualBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
AccrualAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL, AccrualAccountsForSavings.INCOME_FROM_FEES,
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, overdraftAmount, isReversal,
feePayments);
if (isPositive) {
this.helper.createAccrualBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_CONTROL, AccrualAccountsForSavings.INCOME_FROM_FEES, savingsProductId,
paymentTypeId, savingsId, transactionId, transactionDate, amount.subtract(overdraftAmount), isReversal,
feePayments);
}
}
}
else if (savingsTransactionDTO.getTransactionType().isFeeDeduction()) {
// Is the Charge a penalty?
if (penaltyPayments.size() > 0) {
this.helper.createAccrualBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_CONTROL, AccrualAccountsForSavings.INCOME_FROM_PENALTIES, savingsProductId,
paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal, penaltyPayments);
} else {
this.helper.createAccrualBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_CONTROL, AccrualAccountsForSavings.INCOME_FROM_FEES, savingsProductId,
paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal, feePayments);
}
}
/** Handle Transfers proposal **/
else if (savingsTransactionDTO.getTransactionType().isInitiateTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(), AccrualAccountsForSavings.TRANSFERS_SUSPENSE.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
}
/** Handle Transfer Withdrawal or Acceptance **/
else if (savingsTransactionDTO.getTransactionType().isWithdrawTransfer()
|| savingsTransactionDTO.getTransactionType().isApproveTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.TRANSFERS_SUSPENSE.getValue(), AccrualAccountsForSavings.SAVINGS_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
}
/** overdraft **/
else if (savingsTransactionDTO.getTransactionType().isOverdraftInterest()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_REFERENCE.getValue(), AccrualAccountsForSavings.INCOME_FROM_INTEREST.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
} else if (savingsTransactionDTO.getTransactionType().isWrittenoff()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
AccrualAccountsForSavings.LOSSES_WRITTEN_OFF.getValue(),
AccrualAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, amount, isReversal);
} else if (savingsTransactionDTO.getTransactionType().isOverdraftFee()) {
this.helper.createAccrualBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
AccrualAccountsForSavings.SAVINGS_REFERENCE, AccrualAccountsForSavings.INCOME_FROM_FEES, savingsProductId,
paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal, feePayments);
}
}
}
}
@@ -27,6 +27,7 @@ import java.util.Locale;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.accounting.common.AccountingConstants.AccrualAccountsForLoan;
import org.apache.fineract.accounting.common.AccountingConstants.AccrualAccountsForSavings;
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForLoan;
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForSavings;
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForShares;
@@ -211,6 +212,65 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
}
}
private void saveSavingsBaseAccountMapping(final Long savingProductId, final DepositAccountType accountType, final JsonCommand command,
final JsonElement element) {
// asset
this.savingsProductToGLAccountMappingHelper.saveSavingsToAssetAccountMapping(element,
SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(), savingProductId,
CashAccountsForSavings.SAVINGS_REFERENCE.getValue());
if (!accountType.equals(DepositAccountType.RECURRING_DEPOSIT) && !accountType.equals(DepositAccountType.FIXED_DEPOSIT)) {
this.savingsProductToGLAccountMappingHelper.saveSavingsToAssetAccountMapping(element,
SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), savingProductId,
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue());
}
// income
this.savingsProductToGLAccountMappingHelper.saveSavingsToIncomeAccountMapping(element,
SavingProductAccountingParams.INCOME_FROM_FEES.getValue(), savingProductId,
CashAccountsForSavings.INCOME_FROM_FEES.getValue());
this.savingsProductToGLAccountMappingHelper.saveSavingsToIncomeAccountMapping(element,
SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(), savingProductId,
CashAccountsForSavings.INCOME_FROM_PENALTIES.getValue());
if (!accountType.equals(DepositAccountType.RECURRING_DEPOSIT) && !accountType.equals(DepositAccountType.FIXED_DEPOSIT)) {
this.savingsProductToGLAccountMappingHelper.saveSavingsToIncomeAccountMapping(element,
SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue(), savingProductId,
CashAccountsForSavings.INCOME_FROM_INTEREST.getValue());
}
// expenses
this.savingsProductToGLAccountMappingHelper.saveSavingsToExpenseAccountMapping(element,
SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(), savingProductId,
CashAccountsForSavings.INTEREST_ON_SAVINGS.getValue());
if (!accountType.equals(DepositAccountType.RECURRING_DEPOSIT) && !accountType.equals(DepositAccountType.FIXED_DEPOSIT)) {
this.savingsProductToGLAccountMappingHelper.saveSavingsToExpenseAccountMapping(element,
SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(), savingProductId,
CashAccountsForSavings.LOSSES_WRITTEN_OFF.getValue());
}
// liability
this.savingsProductToGLAccountMappingHelper.saveSavingsToLiabilityAccountMapping(element,
SavingProductAccountingParams.SAVINGS_CONTROL.getValue(), savingProductId,
CashAccountsForSavings.SAVINGS_CONTROL.getValue());
this.savingsProductToGLAccountMappingHelper.saveSavingsToLiabilityAccountMapping(element,
SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(), savingProductId,
CashAccountsForSavings.TRANSFERS_SUSPENSE.getValue());
final Boolean isDormancyTrackingActive = this.fromApiJsonHelper.extractBooleanNamed(isDormancyTrackingActiveParamName, element);
if (null != isDormancyTrackingActive && isDormancyTrackingActive) {
this.savingsProductToGLAccountMappingHelper.saveSavingsToLiabilityAccountMapping(element,
SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue(), savingProductId,
CashAccountsForSavings.ESCHEAT_LIABILITY.getValue());
}
// advanced accounting mappings
this.savingsProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, savingProductId, null);
this.savingsProductToGLAccountMappingHelper.saveChargesToIncomeAccountMappings(command, element, savingProductId, null);
}
@Override
@Transactional
public void createSavingProductToGLAccountMapping(final Long savingProductId, final JsonCommand command,
@@ -219,67 +279,28 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
final Integer accountingRuleTypeId = this.fromApiJsonHelper.extractIntegerNamed(accountingRuleParamName, element,
Locale.getDefault());
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(accountingRuleTypeId);
switch (accountingRuleType) {
case NONE:
break;
case CASH_BASED:
// asset
saveSavingsBaseAccountMapping(savingProductId, accountType, command, element);
break;
case ACCRUAL_PERIODIC:
saveSavingsBaseAccountMapping(savingProductId, accountType, command, element);
// assets
this.savingsProductToGLAccountMappingHelper.saveSavingsToAssetAccountMapping(element,
SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(), savingProductId,
CashAccountsForSavings.SAVINGS_REFERENCE.getValue());
SavingProductAccountingParams.FEES_RECEIVABLE.getValue(), savingProductId,
AccrualAccountsForSavings.FEES_RECEIVABLE.getValue());
if (!accountType.equals(DepositAccountType.RECURRING_DEPOSIT) && !accountType.equals(DepositAccountType.FIXED_DEPOSIT)) {
this.savingsProductToGLAccountMappingHelper.saveSavingsToAssetAccountMapping(element,
SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), savingProductId,
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue());
}
// income
this.savingsProductToGLAccountMappingHelper.saveSavingsToIncomeAccountMapping(element,
SavingProductAccountingParams.INCOME_FROM_FEES.getValue(), savingProductId,
CashAccountsForSavings.INCOME_FROM_FEES.getValue());
this.savingsProductToGLAccountMappingHelper.saveSavingsToIncomeAccountMapping(element,
SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(), savingProductId,
CashAccountsForSavings.INCOME_FROM_PENALTIES.getValue());
if (!accountType.equals(DepositAccountType.RECURRING_DEPOSIT) && !accountType.equals(DepositAccountType.FIXED_DEPOSIT)) {
this.savingsProductToGLAccountMappingHelper.saveSavingsToIncomeAccountMapping(element,
SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue(), savingProductId,
CashAccountsForSavings.INCOME_FROM_INTEREST.getValue());
}
// expenses
this.savingsProductToGLAccountMappingHelper.saveSavingsToExpenseAccountMapping(element,
SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(), savingProductId,
CashAccountsForSavings.INTEREST_ON_SAVINGS.getValue());
if (!accountType.equals(DepositAccountType.RECURRING_DEPOSIT) && !accountType.equals(DepositAccountType.FIXED_DEPOSIT)) {
this.savingsProductToGLAccountMappingHelper.saveSavingsToExpenseAccountMapping(element,
SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(), savingProductId,
CashAccountsForSavings.LOSSES_WRITTEN_OFF.getValue());
}
this.savingsProductToGLAccountMappingHelper.saveSavingsToAssetAccountMapping(element,
SavingProductAccountingParams.PENALTIES_RECEIVABLE.getValue(), savingProductId,
AccrualAccountsForSavings.PENALTIES_RECEIVABLE.getValue());
// liability
this.savingsProductToGLAccountMappingHelper.saveSavingsToLiabilityAccountMapping(element,
SavingProductAccountingParams.SAVINGS_CONTROL.getValue(), savingProductId,
CashAccountsForSavings.SAVINGS_CONTROL.getValue());
this.savingsProductToGLAccountMappingHelper.saveSavingsToLiabilityAccountMapping(element,
SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(), savingProductId,
CashAccountsForSavings.TRANSFERS_SUSPENSE.getValue());
final Boolean isDormancyTrackingActive = this.fromApiJsonHelper.extractBooleanNamed(isDormancyTrackingActiveParamName,
element);
if (null != isDormancyTrackingActive && isDormancyTrackingActive) {
this.savingsProductToGLAccountMappingHelper.saveSavingsToLiabilityAccountMapping(element,
SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue(), savingProductId,
CashAccountsForSavings.ESCHEAT_LIABILITY.getValue());
}
// advanced accounting mappings
this.savingsProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, savingProductId, null);
this.savingsProductToGLAccountMappingHelper.saveChargesToIncomeAccountMappings(command, element, savingProductId, null);
SavingProductAccountingParams.INTEREST_PAYABLE.getValue(), savingProductId,
AccrualAccountsForSavings.INTEREST_PAYABLE.getValue());
break;
default:
break;
@@ -359,6 +359,8 @@ public class LoanScheduleAssembler {
CalendarInstance compoundingCalendarInstance = null;
InterestRecalculationCompoundingMethod compoundingMethod = null;
boolean allowCompoundingOnEod = false;
final Boolean isFloatingInterestRate = this.fromApiJsonHelper
.extractBooleanNamed(LoanApiConstants.isFloatingInterestRateParameterName, element);
if (isInterestRecalculationEnabled) {
LoanProductInterestRecalculationDetails loanProductInterestRecalculationDetails = loanProduct
.getProductInterestRecalculationDetails();
@@ -409,8 +411,7 @@ public class LoanScheduleAssembler {
if (loanProduct.isLinkedToFloatingInterestRate()) {
final BigDecimal interestRateDiff = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(LoanApiConstants.interestRateDifferentialParameterName, element);
final Boolean isFloatingInterestRate = this.fromApiJsonHelper
.extractBooleanNamed(LoanApiConstants.isFloatingInterestRateParameterName, element);
List<FloatingRatePeriodData> baseLendingRatePeriods = null;
try {
baseLendingRatePeriods = this.floatingRatesReadPlatformService.retrieveBaseLendingRate().getRatePeriods();
@@ -33,10 +33,9 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.accounting.common.AccountingConstants.LoanProductAccountingParams;
import org.apache.fineract.accounting.common.AccountingRuleType;
import org.apache.fineract.accounting.common.AccountingValidations;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
@@ -65,7 +64,6 @@ import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyTy
import org.apache.fineract.portfolio.loanproduct.exception.EqualAmortizationUnsupportedFeatureException;
import org.springframework.stereotype.Component;
@Slf4j
@RequiredArgsConstructor
@Component
public final class LoanProductDataValidator {
@@ -613,7 +611,8 @@ public final class LoanProductDataValidator {
final Integer accountingRuleType = this.fromApiJsonHelper.extractIntegerNamed(ACCOUNTING_RULE, element, Locale.getDefault());
baseDataValidator.reset().parameter(ACCOUNTING_RULE).value(accountingRuleType).notNull().inMinMaxRange(1, 4);
if (isCashBasedAccounting(accountingRuleType) || isAccrualBasedAccounting(accountingRuleType)) {
if (AccountingValidations.isCashBasedAccounting(accountingRuleType)
|| AccountingValidations.isAccrualBasedAccounting(accountingRuleType)) {
final Long fundAccountId = this.fromApiJsonHelper.extractLongNamed(LoanProductAccountingParams.FUND_SOURCE.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.FUND_SOURCE.getValue()).value(fundAccountId).notNull()
@@ -709,7 +708,7 @@ public final class LoanProductDataValidator {
}
if (isAccrualBasedAccounting(accountingRuleType)) {
if (AccountingValidations.isAccrualBasedAccounting(accountingRuleType)) {
final Long receivableInterestAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.INTEREST_RECEIVABLE.getValue(), element);
@@ -2144,22 +2143,6 @@ public final class LoanProductDataValidator {
}
}
private boolean isCashBasedAccounting(final Integer accountingRuleType) {
return AccountingRuleType.CASH_BASED.getValue().equals(accountingRuleType);
}
private boolean isAccrualBasedAccounting(final Integer accountingRuleType) {
return isUpfrontAccrualAccounting(accountingRuleType) || isPeriodicAccounting(accountingRuleType);
}
private boolean isUpfrontAccrualAccounting(final Integer accountingRuleType) {
return AccountingRuleType.ACCRUAL_UPFRONT.getValue().equals(accountingRuleType);
}
private boolean isPeriodicAccounting(final Integer accountingRuleType) {
return AccountingRuleType.ACCRUAL_PERIODIC.getValue().equals(accountingRuleType);
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
@@ -318,88 +318,31 @@ final class FixedDepositProductsApiResourceSwagger {
public String description;
}
static final class GetFixedDepositProductsGlAccount {
private GetFixedDepositProductsGlAccount() {}
@Schema(example = "12")
public Long id;
@Schema(example = "savings ref")
public String name;
@Schema(example = "20")
public Integer glCode;
}
static final class GetFixedDepositProductsProductIdAccountingMappings {
private GetFixedDepositProductsProductIdAccountingMappings() {}
static final class GetFixedDepositProductsProductIdSavingsReferenceAccount {
private GetFixedDepositProductsProductIdSavingsReferenceAccount() {}
@Schema(example = "12")
public Long id;
@Schema(example = "savings ref")
public String name;
@Schema(example = "20")
public String glCode;
}
static final class GetFixedDepositProductsProductIdIncomeFromFeeAccount {
private GetFixedDepositProductsProductIdIncomeFromFeeAccount() {}
@Schema(example = "16")
public Long id;
@Schema(example = "income from savings fee")
public String name;
@Schema(example = "24")
public String glCode;
}
static final class GetFixedDepositProductsProductIdIncomeFromPenaltyAccount {
private GetFixedDepositProductsProductIdIncomeFromPenaltyAccount() {}
@Schema(example = "17")
public Long id;
@Schema(example = "income from sav penalties")
public String name;
@Schema(example = "25")
public String glCode;
}
static final class GetFixedDepositProductsProductIdInterestOnSavingsAccount {
private GetFixedDepositProductsProductIdInterestOnSavingsAccount() {}
@Schema(example = "15")
public Long id;
@Schema(example = "interest on savings")
public String name;
@Schema(example = "23")
public String glCode;
}
static final class GetFixedDepositProductsProductIdSavingsControlAccount {
private GetFixedDepositProductsProductIdSavingsControlAccount() {}
@Schema(example = "13")
public Long id;
@Schema(example = "savings ref tool kit")
public String name;
@Schema(example = "21")
public String glCode;
}
static final class GetFixedDepositProductsProductIdTransfersInSuspenseAccount {
private GetFixedDepositProductsProductIdTransfersInSuspenseAccount() {}
@Schema(example = "14")
public Long id;
@Schema(example = "saving transfers")
public String name;
@Schema(example = "22")
public String glCode;
}
public GetFixedDepositProductsProductIdSavingsReferenceAccount savingsReferenceAccount;
public GetFixedDepositProductsProductIdIncomeFromFeeAccount incomeFromFeeAccount;
public GetFixedDepositProductsProductIdIncomeFromPenaltyAccount incomeFromPenaltyAccount;
public GetFixedDepositProductsProductIdInterestOnSavingsAccount interestOnSavingsAccount;
public GetFixedDepositProductsProductIdSavingsControlAccount savingsControlAccount;
public GetFixedDepositProductsProductIdTransfersInSuspenseAccount transfersInSuspenseAccount;
public GetFixedDepositProductsGlAccount savingsReferenceAccount;
public GetFixedDepositProductsGlAccount feeReceivableAccount;
public GetFixedDepositProductsGlAccount penaltyReceivableAccount;
public GetFixedDepositProductsGlAccount incomeFromFeeAccount;
public GetFixedDepositProductsGlAccount incomeFromPenaltyAccount;
public GetFixedDepositProductsGlAccount interestOnSavingsAccount;
public GetFixedDepositProductsGlAccount savingsControlAccount;
public GetFixedDepositProductsGlAccount transfersInSuspenseAccount;
public GetFixedDepositProductsGlAccount interestPayableAccount;
}
static final class GetFixedDepositProductsProductIdFeeToIncomeAccountMappings {
@@ -455,7 +398,7 @@ final class FixedDepositProductsApiResourceSwagger {
}
public GetFixedDepositProductsProductIdPenaltyToIncomeAccountMappingsCharge charge;
public GetFixedDepositProductsProductIdAccountingMappings.GetFixedDepositProductsProductIdIncomeFromPenaltyAccount incomeAccount;
public GetFixedDepositProductsGlAccount incomeAccount;
}
static final class GetFixedDepositProductsProductIdPreClosurePenalInterestOnType {
@@ -343,88 +343,30 @@ final class RecurringDepositProductsApiResourceSwagger {
public String description;
}
static final class GetRecurringDepositProductsGlAccount {
private GetRecurringDepositProductsGlAccount() {}
@Schema(example = "12")
public Long id;
@Schema(example = "savings control")
public String name;
@Schema(example = "2000001")
public String glCode;
}
static final class GetRecurringDepositProductsProductIdAccountingMappings {
private GetRecurringDepositProductsProductIdAccountingMappings() {}
static final class GetRecurringDepositProductsProductIdSavingsReferenceAccount {
private GetRecurringDepositProductsProductIdSavingsReferenceAccount() {}
@Schema(example = "12")
public Long id;
@Schema(example = "savings ref")
public String name;
@Schema(example = "20")
public String glCode;
}
static final class GetRecurringDepositProductsProductIdIncomeFromFeeAccount {
private GetRecurringDepositProductsProductIdIncomeFromFeeAccount() {}
@Schema(example = "16")
public Long id;
@Schema(example = "income from savings fee")
public String name;
@Schema(example = "24")
public String glCode;
}
static final class GetRecurringDepositProductsProductIdIncomeFromPenaltyAccount {
private GetRecurringDepositProductsProductIdIncomeFromPenaltyAccount() {}
@Schema(example = "17")
public Long id;
@Schema(example = "income from sav penalties")
public String name;
@Schema(example = "25")
public String glCode;
}
static final class GetRecurringDepositProductsProductIdInterestOnSavingsAccount {
private GetRecurringDepositProductsProductIdInterestOnSavingsAccount() {}
@Schema(example = "15")
public Long id;
@Schema(example = "interest on savings")
public String name;
@Schema(example = "23")
public String glCode;
}
static final class GetRecurringDepositProductsProductIdSavingsControlAccount {
private GetRecurringDepositProductsProductIdSavingsControlAccount() {}
@Schema(example = "13")
public Long id;
@Schema(example = "savings ref tool kit")
public String name;
@Schema(example = "21")
public String glCode;
}
static final class GetRecurringDepositProductsProductIdTransfersInSuspenseAccount {
private GetRecurringDepositProductsProductIdTransfersInSuspenseAccount() {}
@Schema(example = "14")
public Long id;
@Schema(example = "saving transfers")
public String name;
@Schema(example = "22")
public String glCode;
}
public GetRecurringDepositProductsProductIdSavingsReferenceAccount savingsReferenceAccount;
public GetRecurringDepositProductsProductIdIncomeFromFeeAccount incomeFromFeeAccount;
public GetRecurringDepositProductsProductIdIncomeFromPenaltyAccount incomeFromPenaltyAccount;
public GetRecurringDepositProductsProductIdInterestOnSavingsAccount interestOnSavingsAccount;
public GetRecurringDepositProductsProductIdSavingsControlAccount savingsControlAccount;
public GetRecurringDepositProductsProductIdTransfersInSuspenseAccount transfersInSuspenseAccount;
public GetRecurringDepositProductsGlAccount incomeFromFeeAccount;
public GetRecurringDepositProductsGlAccount incomeFromPenaltyAccount;
public GetRecurringDepositProductsGlAccount interestOnSavingsAccount;
public GetRecurringDepositProductsGlAccount savingsControlAccount;
public GetRecurringDepositProductsGlAccount transfersInSuspenseAccount;
public GetRecurringDepositProductsGlAccount feeReceivableAccount;
public GetRecurringDepositProductsGlAccount penaltyReceivableAccount;
public GetRecurringDepositProductsGlAccount interestPayableAccount;
}
static final class GetRecurringDepositProductsProductIdFeeToIncomeAccountMappings {
@@ -480,7 +422,7 @@ final class RecurringDepositProductsApiResourceSwagger {
}
public GetRecurringDepositProductsProductIdPenaltyToIncomeAccountMappingsCharge charge;
public GetRecurringDepositProductsProductIdAccountingMappings.GetRecurringDepositProductsProductIdIncomeFromPenaltyAccount incomeAccount;
public GetRecurringDepositProductsGlAccount incomeAccount;
}
static final class GetRecurringDepositProductsProductIdPreClosurePenalInterestOnType {
@@ -226,88 +226,34 @@ final class SavingsProductsApiResourceSwagger {
private GetSavingsProductsProductIdResponse() {}
static final class GetSavingsProductsGlAccount {
private GetSavingsProductsGlAccount() {}
@Schema(example = "12")
public Integer id;
@Schema(example = "savings control")
public String name;
@Schema(example = "2000001")
public String glCode;
}
static final class GetSavingsProductsAccountingMappings {
private GetSavingsProductsAccountingMappings() {}
static final class GetSavingsProductsSavingsReferenceAccount {
private GetSavingsProductsSavingsReferenceAccount() {}
@Schema(example = "12")
public Integer id;
@Schema(example = "savings ref")
public String name;
@Schema(example = "20")
public String glCode;
}
static final class GetSavingsProductsIncomeFromFeeAccount {
private GetSavingsProductsIncomeFromFeeAccount() {}
@Schema(example = "16")
public Integer id;
@Schema(example = "income from savings fee")
public String name;
@Schema(example = "24")
public String glCode;
}
static final class GetSavingsProductsIncomeFromPenaltyAccount {
private GetSavingsProductsIncomeFromPenaltyAccount() {}
@Schema(example = "17")
public Integer id;
@Schema(example = "income from sav penalties")
public String name;
@Schema(example = "25")
public String glCode;
}
static final class GetSavingsProductsInterestOnSavingsAccount {
private GetSavingsProductsInterestOnSavingsAccount() {}
@Schema(example = "15")
public Integer id;
@Schema(example = "interest on savings")
public String name;
@Schema(example = "23")
public String glCode;
}
static final class GetSavingsProductsSavingsControlAccount {
private GetSavingsProductsSavingsControlAccount() {}
@Schema(example = "13")
public Integer id;
@Schema(example = "savings ref tool kit")
public String name;
@Schema(example = "21")
public String glCode;
}
static final class GetSavingsProductsTransfersInSuspenseAccount {
private GetSavingsProductsTransfersInSuspenseAccount() {}
@Schema(example = "14")
public Integer id;
@Schema(example = "saving transfers")
public String name;
@Schema(example = "22")
public String glCode;
}
public GetSavingsProductsSavingsReferenceAccount savingsReferenceAccount;
public GetSavingsProductsIncomeFromFeeAccount incomeFromFeeAccount;
public GetSavingsProductsIncomeFromPenaltyAccount incomeFromPenaltyAccount;
public GetSavingsProductsInterestOnSavingsAccount interestOnSavingsAccount;
public GetSavingsProductsSavingsControlAccount savingsControlAccount;
public GetSavingsProductsTransfersInSuspenseAccount transfersInSuspenseAccount;
public GetSavingsProductsGlAccount savingsReferenceAccount;
public GetSavingsProductsGlAccount overdraftPortfolioControl;
public GetSavingsProductsGlAccount feeReceivableAccount;
public GetSavingsProductsGlAccount penaltyReceivableAccount;
public GetSavingsProductsGlAccount incomeFromFeeAccount;
public GetSavingsProductsGlAccount incomeFromPenaltyAccount;
public GetSavingsProductsGlAccount incomeFromInterest;
public GetSavingsProductsGlAccount interestOnSavingsAccount;
public GetSavingsProductsGlAccount writeOffAccount;
public GetSavingsProductsGlAccount savingsControlAccount;
public GetSavingsProductsGlAccount transfersInSuspenseAccount;
public GetSavingsProductsGlAccount interestPayableAccount;
}
static final class GetSavingsProductsPaymentChannelToFundSourceMappings {
@@ -393,7 +339,7 @@ final class SavingsProductsApiResourceSwagger {
}
public GetSavingsProductsPenaltyToIncomeAccountMappingsCharge charge;
public GetSavingsProductsAccountingMappings.GetSavingsProductsIncomeFromPenaltyAccount incomeAccount;
public GetSavingsProductsGlAccount incomeAccount;
}
@Schema(example = "1")
@@ -71,35 +71,33 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.accounting.common.AccountingConstants.SavingProductAccountingParams;
import org.apache.fineract.accounting.common.AccountingRuleType;
import org.apache.fineract.accounting.common.AccountingValidations;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.interestratechart.data.InterestRateChartDataValidator;
import org.apache.fineract.portfolio.savings.DepositAccountType;
import org.apache.fineract.portfolio.savings.PreClosurePenalInterestOnType;
import org.apache.fineract.portfolio.savings.SavingsApiConstants;
import org.apache.fineract.portfolio.savings.SavingsCompoundingInterestPeriodType;
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationDaysInYearType;
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationType;
import org.apache.fineract.portfolio.savings.SavingsPeriodFrequencyType;
import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class DepositProductDataValidator {
private final FromJsonHelper fromApiJsonHelper;
private final InterestRateChartDataValidator chartDataValidator;
@Autowired
public DepositProductDataValidator(FromJsonHelper fromApiJsonHelper, InterestRateChartDataValidator chartDataValidator) {
this.fromApiJsonHelper = fromApiJsonHelper;
this.chartDataValidator = chartDataValidator;
}
private final SavingsProductAccountingDataValidator savingsProductAccountingDataValidator;
public void validateForFixedDepositCreate(final String json) {
if (StringUtils.isBlank(json)) {
@@ -115,7 +113,7 @@ public class DepositProductDataValidator {
final JsonElement element = this.fromApiJsonHelper.parse(json);
validateDepositDetailForCreate(element, this.fromApiJsonHelper, baseDataValidator);
validateDepositDetailForCreate(element, this.fromApiJsonHelper, baseDataValidator, DepositAccountType.FIXED_DEPOSIT);
validatePreClosureDetailForCreate(element, baseDataValidator);
@@ -168,7 +166,7 @@ public class DepositProductDataValidator {
final JsonElement element = this.fromApiJsonHelper.parse(json);
validateDepositDetailForCreate(element, this.fromApiJsonHelper, baseDataValidator);
validateDepositDetailForCreate(element, this.fromApiJsonHelper, baseDataValidator, DepositAccountType.RECURRING_DEPOSIT);
validatePreClosureDetailForCreate(element, baseDataValidator);
@@ -212,7 +210,7 @@ public class DepositProductDataValidator {
}
private void validateDepositDetailForCreate(final JsonElement element, final FromJsonHelper fromApiJsonHelper,
final DataValidatorBuilder baseDataValidator) {
final DataValidatorBuilder baseDataValidator, final DepositAccountType accountType) {
final String name = fromApiJsonHelper.extractStringNamed(nameParamName, element);
baseDataValidator.reset().parameter(nameParamName).value(name).notBlank().notExceedingLengthOf(100);
@@ -258,13 +256,6 @@ public class DepositProductDataValidator {
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType).notNull()
.isOneOfTheseValues(SavingsInterestCalculationDaysInYearType.integerValues());
/*
* if (fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName , element)) { final BigDecimal
* minOpeningBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed (minRequiredOpeningBalanceParamName,
* element); baseDataValidator.reset ().parameter(minRequiredOpeningBalanceParamName
* ).value(minOpeningBalance).zeroOrPositiveAmount(); }
*/
if (fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
final Integer lockinPeriodFrequency = fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName, element);
@@ -302,40 +293,16 @@ public class DepositProductDataValidator {
final Integer accountingRuleType = fromApiJsonHelper.extractIntegerNamed("accountingRule", element, Locale.getDefault());
baseDataValidator.reset().parameter("accountingRule").value(accountingRuleType).notNull().inMinMaxRange(1, 3);
if (isCashBasedAccounting(accountingRuleType)) {
Boolean isDormancyActive = this.fromApiJsonHelper.extractBooleanNamed(SavingsApiConstants.isDormancyTrackingActiveParamName,
element);
if (isDormancyActive == null) {
isDormancyActive = false;
}
final Long savingsControlAccountId = fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.SAVINGS_CONTROL.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.SAVINGS_CONTROL.getValue()).value(savingsControlAccountId)
.notNull().integerGreaterThanZero();
final Long savingsReferenceAccountId = fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue()).value(savingsReferenceAccountId)
.notNull().integerGreaterThanZero();
final Long transfersInSuspenseAccountId = fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue())
.value(transfersInSuspenseAccountId).notNull().integerGreaterThanZero();
final Long interestOnSavingsAccountId = fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue())
.value(interestOnSavingsAccountId).notNull().integerGreaterThanZero();
final Long incomeFromFeeId = fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_FEES.getValue(),
element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_FEES.getValue()).value(incomeFromFeeId).notNull()
.integerGreaterThanZero();
final Long incomeFromPenaltyId = fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue()).value(incomeFromPenaltyId)
.notNull().integerGreaterThanZero();
validatePaymentChannelFundSourceMappings(fromApiJsonHelper, baseDataValidator, element);
validateChargeToIncomeAccountMappings(fromApiJsonHelper, baseDataValidator, element);
if (AccountingValidations.isCashBasedAccounting(accountingRuleType)
|| AccountingValidations.isAccrualPeriodicBasedAccounting(accountingRuleType)) {
savingsProductAccountingDataValidator.evaluateProductAccountingData(accountingRuleType, isDormancyActive, element,
baseDataValidator, accountType);
}
validateTaxWithHoldingParams(baseDataValidator, element, true);
@@ -542,8 +509,8 @@ public class DepositProductDataValidator {
baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue()).value(incomeFromPenaltyId)
.ignoreIfNull().integerGreaterThanZero();
validatePaymentChannelFundSourceMappings(fromApiJsonHelper, baseDataValidator, element);
validateChargeToIncomeAccountMappings(fromApiJsonHelper, baseDataValidator, element);
savingsProductAccountingDataValidator.validatePaymentChannelFundSourceMappings(baseDataValidator, element);
savingsProductAccountingDataValidator.validateChargeToIncomeAccountMappings(baseDataValidator, element);
validateTaxWithHoldingParams(baseDataValidator, element, false);
}
@@ -611,76 +578,6 @@ public class DepositProductDataValidator {
}
}
private boolean isCashBasedAccounting(final Integer accountingRuleType) {
return AccountingRuleType.CASH_BASED.getValue().equals(accountingRuleType);
}
/**
* Validation for advanced accounting options
*/
private void validatePaymentChannelFundSourceMappings(final FromJsonHelper fromApiJsonHelper,
final DataValidatorBuilder baseDataValidator, final JsonElement element) {
if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element)) {
final JsonArray paymentChannelMappingArray = fromApiJsonHelper
.extractJsonArrayNamed(SavingProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element);
if (paymentChannelMappingArray != null && paymentChannelMappingArray.size() > 0) {
int i = 0;
do {
final JsonObject jsonObject = paymentChannelMappingArray.get(i).getAsJsonObject();
final Long paymentTypeId = jsonObject.get(SavingProductAccountingParams.PAYMENT_TYPE.getValue()).getAsLong();
final Long paymentSpecificFundAccountId = jsonObject.get(SavingProductAccountingParams.FUND_SOURCE.getValue())
.getAsLong();
baseDataValidator.reset()
.parameter(SavingProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue() + "[" + i + "]."
+ SavingProductAccountingParams.PAYMENT_TYPE.toString())
.value(paymentTypeId).notNull().integerGreaterThanZero();
baseDataValidator.reset()
.parameter(SavingProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue() + "[" + i + "]."
+ SavingProductAccountingParams.FUND_SOURCE.getValue())
.value(paymentSpecificFundAccountId).notNull().integerGreaterThanZero();
i++;
} while (i < paymentChannelMappingArray.size());
}
}
}
private void validateChargeToIncomeAccountMappings(final FromJsonHelper fromApiJsonHelper, final DataValidatorBuilder baseDataValidator,
final JsonElement element) {
// validate for both fee and penalty charges
validateChargeToIncomeAccountMappings(fromApiJsonHelper, baseDataValidator, element, true);
validateChargeToIncomeAccountMappings(fromApiJsonHelper, baseDataValidator, element, true);
}
private void validateChargeToIncomeAccountMappings(final FromJsonHelper fromApiJsonHelper, final DataValidatorBuilder baseDataValidator,
final JsonElement element, final boolean isPenalty) {
String parameterName;
if (isPenalty) {
parameterName = SavingProductAccountingParams.PENALTY_INCOME_ACCOUNT_MAPPING.getValue();
} else {
parameterName = SavingProductAccountingParams.FEE_INCOME_ACCOUNT_MAPPING.getValue();
}
if (fromApiJsonHelper.parameterExists(parameterName, element)) {
final JsonArray chargeToIncomeAccountMappingArray = fromApiJsonHelper.extractJsonArrayNamed(parameterName, element);
if (chargeToIncomeAccountMappingArray != null && chargeToIncomeAccountMappingArray.size() > 0) {
int i = 0;
do {
final JsonObject jsonObject = chargeToIncomeAccountMappingArray.get(i).getAsJsonObject();
final Long chargeId = fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.CHARGE_ID.getValue(),
jsonObject);
final Long incomeAccountId = fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.INCOME_ACCOUNT_ID.getValue(), jsonObject);
baseDataValidator.reset().parameter(parameterName + "[" + i + "]." + SavingProductAccountingParams.CHARGE_ID.getValue())
.value(chargeId).notNull().integerGreaterThanZero();
baseDataValidator.reset()
.parameter(parameterName + "[" + i + "]." + SavingProductAccountingParams.INCOME_ACCOUNT_ID.getValue())
.value(incomeAccountId).notNull().integerGreaterThanZero();
i++;
} while (i < chargeToIncomeAccountMappingArray.size());
}
}
}
public void validateRecurringDetailForCreate(JsonElement element, DataValidatorBuilder baseDataValidator) {
final Boolean isMandatoryDeposit = this.fromApiJsonHelper.extractBooleanNamed(isMandatoryDepositParamName, element);
@@ -43,6 +43,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
@@ -55,15 +56,14 @@ import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.portfolio.savings.SavingsApiConstants;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountSubStatusEnum;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
import org.apache.fineract.portfolio.savings.exception.TransactionBeforePivotDateNotAllowed;
import org.apache.fineract.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class SavingsAccountTransactionDataValidator {
private final FromJsonHelper fromApiJsonHelper;
@@ -71,15 +71,6 @@ public class SavingsAccountTransactionDataValidator {
Arrays.asList(transactionDateParamName, SavingsApiConstants.dateFormatParamName, SavingsApiConstants.localeParamName,
transactionAmountParamName, lienAllowedParamName, SavingsApiConstants.reasonForBlockParamName));
private final ConfigurationDomainService configurationDomainService;
private final SavingsAccountAssembler savingAccountAssembler;
@Autowired
public SavingsAccountTransactionDataValidator(final FromJsonHelper fromApiJsonHelper,
final ConfigurationDomainService configurationDomainService, final SavingsAccountAssembler savingAccountAssembler) {
this.fromApiJsonHelper = fromApiJsonHelper;
this.configurationDomainService = configurationDomainService;
this.savingAccountAssembler = savingAccountAssembler;
}
public void validateTransactionWithPivotDate(final LocalDate transactionDate, final SavingsAccount savingsAccount) {
final boolean backdatedTxnsAllowedTill = this.configurationDomainService.retrievePivotDateConfig();
@@ -99,7 +99,6 @@ import org.springframework.jdbc.core.RowMapper;
import org.springframework.util.CollectionUtils;
@RequiredArgsConstructor
public class DepositAccountReadPlatformServiceImpl implements DepositAccountReadPlatformService {
private static final FixedDepositAccountMapper FIXED_DEPOSIT_ACCOUNT_MAPPER = new FixedDepositAccountMapper();
@@ -611,7 +611,6 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
final BigDecimal outstandingChargeAmount = null;
final BigDecimal runningBalance = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "runningBalance");
final boolean reversed = rs.getBoolean("reversed");
final boolean isManualTransaction = rs.getBoolean("manualTransaction");
final Long officeId = rs.getLong("officeId");
final BigDecimal cumulativeBalance = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "cumulativeBalance");
@@ -684,59 +683,6 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
}
return savingsAccountDataList;
// final String productName = rs.getString("productName");
// final String fieldOfficerName = rs.getString("fieldOfficerName");
// final String submittedByUsername = rs.getString("submittedByUsername");
// final String submittedByFirstname = rs.getString("submittedByFirstname");
// final String submittedByLastname = rs.getString("submittedByLastname");
//
// final String rejectedByUsername = rs.getString("rejectedByUsername");
// final String rejectedByFirstname = rs.getString("rejectedByFirstname");
// final String rejectedByLastname = rs.getString("rejectedByLastname");
//
// final String withdrawnByUsername = rs.getString("withdrawnByUsername");
// final String withdrawnByFirstname = rs.getString("withdrawnByFirstname");
// final String withdrawnByLastname = rs.getString("withdrawnByLastname");
// final String approvedByUsername = rs.getString("approvedByUsername");
// final String approvedByFirstname = rs.getString("approvedByFirstname");
// final String approvedByLastname = rs.getString("approvedByLastname");
// final String activatedByUsername = rs.getString("activatedByUsername");
// final String activatedByFirstname = rs.getString("activatedByFirstname");
// final String activatedByLastname = rs.getString("activatedByLastname");
// final String closedByUsername = rs.getString("closedByUsername");
// final String closedByFirstname = rs.getString("closedByFirstname");
// final String closedByLastname = rs.getString("closedByLastname");
// final String currencyName = rs.getString("currencyName");
// final String currencyNameCode = rs.getString("currencyNameCode");
// final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
/*
* final BigDecimal withdrawalFeeAmount = rs.getBigDecimal("withdrawalFeeAmount");
*
* EnumOptionData withdrawalFeeType = null; final Integer withdrawalFeeTypeValue =
* JdbcSupport.getInteger(rs, "withdrawalFeeTypeEnum"); if (withdrawalFeeTypeValue != null) {
* withdrawalFeeType = SavingsEnumerations.withdrawalFeeType(withdrawalFeeTypeValue); }
*/
/*
* final BigDecimal annualFeeAmount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "annualFeeAmount");
*
* MonthDay annualFeeOnMonthDay = null; final Integer annualFeeOnMonth = JdbcSupport.getInteger(rs,
* "annualFeeOnMonth"); final Integer annualFeeOnDay = JdbcSupport.getInteger(rs, "annualFeeOnDay"); if
* (annualFeeAmount != null && annualFeeOnDay != null) { annualFeeOnMonthDay = new
* MonthDay(annualFeeOnMonth, annualFeeOnDay); }
*
* final LocalDate annualFeeNextDueDate = JdbcSupport.getLocalDate(rs, "annualFeeNextDueDate");
*/
}
}
@@ -792,20 +738,12 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
sqlBuilder.append("sa.min_required_opening_balance as minRequiredOpeningBalance, ");
sqlBuilder.append("sa.lockin_period_frequency as lockinPeriodFrequency,");
sqlBuilder.append("sa.lockin_period_frequency_enum as lockinPeriodFrequencyType, ");
// sqlBuilder.append("sa.withdrawal_fee_amount as
// withdrawalFeeAmount,");
// sqlBuilder.append("sa.withdrawal_fee_type_enum as
// withdrawalFeeTypeEnum, ");
sqlBuilder.append("sa.allow_overdraft as allowOverdraft, ");
sqlBuilder.append("sa.overdraft_limit as overdraftLimit, ");
sqlBuilder.append("sa.nominal_annual_interest_rate_overdraft as nominalAnnualInterestRateOverdraft, ");
sqlBuilder.append("sa.min_overdraft_for_interest_calculation as minOverdraftForInterestCalculation, ");
// sqlBuilder.append("sa.annual_fee_amount as annualFeeAmount,");
// sqlBuilder.append("sa.annual_fee_on_month as annualFeeOnMonth,
// ");
// sqlBuilder.append("sa.annual_fee_on_day as annualFeeOnDay, ");
// sqlBuilder.append("sa.annual_fee_next_due_date as
// annualFeeNextDueDate, ");
sqlBuilder.append("sa.total_deposits_derived as totalDeposits, ");
sqlBuilder.append("sa.total_withdrawals_derived as totalWithdrawals, ");
sqlBuilder.append("sa.total_withdrawal_fees_derived as totalWithdrawalFees, ");
@@ -981,14 +919,6 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
lockinPeriodFrequencyType = SavingsEnumerations.lockinPeriodFrequencyType(lockinPeriodType);
}
/*
* final BigDecimal withdrawalFeeAmount = rs.getBigDecimal("withdrawalFeeAmount");
*
* EnumOptionData withdrawalFeeType = null; final Integer withdrawalFeeTypeValue =
* JdbcSupport.getInteger(rs, "withdrawalFeeTypeEnum"); if (withdrawalFeeTypeValue != null) {
* withdrawalFeeType = SavingsEnumerations.withdrawalFeeType(withdrawalFeeTypeValue); }
*/
final boolean withdrawalFeeForTransfers = rs.getBoolean("withdrawalFeeForTransfers");
final boolean allowOverdraft = rs.getBoolean("allowOverdraft");
@@ -1004,16 +934,6 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
final BigDecimal maxAllowedLienLimit = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "maxAllowedLienLimit");
final boolean lienAllowed = rs.getBoolean("lienAllowed");
/*
* final BigDecimal annualFeeAmount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "annualFeeAmount");
*
* MonthDay annualFeeOnMonthDay = null; final Integer annualFeeOnMonth = JdbcSupport.getInteger(rs,
* "annualFeeOnMonth"); final Integer annualFeeOnDay = JdbcSupport.getInteger(rs, "annualFeeOnDay"); if
* (annualFeeAmount != null && annualFeeOnDay != null) { annualFeeOnMonthDay = new
* MonthDay(annualFeeOnMonth, annualFeeOnDay); }
*
* final LocalDate annualFeeNextDueDate = JdbcSupport.getLocalDate(rs, "annualFeeNextDueDate");
*/
final BigDecimal totalDeposits = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "totalDeposits");
final BigDecimal totalWithdrawals = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "totalWithdrawals");
final BigDecimal totalWithdrawalFees = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "totalWithdrawalFees");
@@ -59,11 +59,7 @@ public class SavingsDropdownReadPlatformServiceImpl implements SavingsDropdownRe
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.MONTHLY),
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.QUATERLY),
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.BI_ANNUAL),
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.ANNUAL)
// //
// SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.NO_COMPOUNDING_SIMPLE_INTEREST)
// //
);
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.ANNUAL));
return allowedOptions;
}