Merge pull request #619 from vishwasbabu/mifosplatform-1.10.3
handle overpayments and refunds in accounting
This commit is contained in:
+16
@@ -0,0 +1,16 @@
|
||||
/***Set defaults for income from Penalties for existing Saving Products**/
|
||||
ALTER TABLE `m_loan_transaction`
|
||||
ADD COLUMN `overpayment_portion_derived` DECIMAL(19,6) NULL DEFAULT NULL AFTER `penalty_charges_portion_derived`;
|
||||
|
||||
/**Add dummy liability account if organization already has a loan product with accounting enabled**/
|
||||
INSERT INTO `acc_gl_account` (`name`, `hierarchy`, `gl_code`, `classification_enum`,`description`)
|
||||
select 'Loan Overpayments (Temp)', '.', '22000-Temp', 2,'Temporary account to track Loan overpayments Liabilities'
|
||||
FROM m_product_loan WHERE accounting_type != 1
|
||||
limit 1;
|
||||
|
||||
|
||||
/**Map a liability account for every loan which has accounting enabled**/
|
||||
INSERT INTO `acc_product_mapping` (`gl_account_id`,`product_id`,`product_type`,`financial_account_type`)
|
||||
select (select id from acc_gl_account where classification_enum=2 and account_usage=1 LIMIT 1), mapping.product_id, mapping.product_type, 11
|
||||
from acc_product_mapping mapping
|
||||
where mapping.financial_account_type = 2 and mapping.product_type=1;
|
||||
+8
-8
@@ -13,7 +13,7 @@ public class AccountingConstants {
|
||||
/*** Accounting placeholders for cash based accounting for loan products ***/
|
||||
public static enum CASH_ACCOUNTS_FOR_LOAN {
|
||||
FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), LOSSES_WRITTEN_OFF(6), TRANSFERS_SUSPENSE(
|
||||
10);
|
||||
10), OVERPAYMENT(11);
|
||||
|
||||
private final Integer value;
|
||||
|
||||
@@ -46,7 +46,7 @@ public class AccountingConstants {
|
||||
/*** Accounting placeholders for accrual based accounting for loan products ***/
|
||||
public static enum ACCRUAL_ACCOUNTS_FOR_LOAN {
|
||||
FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), LOSSES_WRITTEN_OFF(6), INTEREST_RECEIVABLE(
|
||||
7), FEES_RECEIVABLE(8), PENALTIES_RECEIVABLE(9), TRANSFERS_SUSPENSE(10);
|
||||
7), FEES_RECEIVABLE(8), PENALTIES_RECEIVABLE(9), TRANSFERS_SUSPENSE(10), OVERPAYMENT(11);
|
||||
|
||||
private final Integer value;
|
||||
|
||||
@@ -83,12 +83,12 @@ public class AccountingConstants {
|
||||
***/
|
||||
public static enum LOAN_PRODUCT_ACCOUNTING_PARAMS {
|
||||
FUND_SOURCE("fundSourceAccountId"), LOAN_PORTFOLIO("loanPortfolioAccountId"), INTEREST_ON_LOANS("interestOnLoanAccountId"), INCOME_FROM_FEES(
|
||||
"incomeFromFeeAccountId"), INCOME_FROM_PENALTIES("incomeFromPenaltyAccountId"), LOSSES_WRITTEN_OFF("writeOffAccountId"), INTEREST_RECEIVABLE(
|
||||
"receivableInterestAccountId"), FEES_RECEIVABLE("receivableFeeAccountId"), PENALTIES_RECEIVABLE(
|
||||
"receivablePenaltyAccountId"), TRANSFERS_SUSPENSE("transfersInSuspenseAccountId"), PAYMENT_CHANNEL_FUND_SOURCE_MAPPING(
|
||||
"paymentChannelToFundSourceMappings"), PAYMENT_TYPE("paymentTypeId"), FEE_INCOME_ACCOUNT_MAPPING(
|
||||
"feeToIncomeAccountMappings"), PENALTY_INCOME_ACCOUNT_MAPPING("penaltyToIncomeAccountMappings"), CHARGE_ID("chargeId"), INCOME_ACCOUNT_ID(
|
||||
"incomeAccountId");
|
||||
"incomeFromFeeAccountId"), INCOME_FROM_PENALTIES("incomeFromPenaltyAccountId"), LOSSES_WRITTEN_OFF("writeOffAccountId"), OVERPAYMENT(
|
||||
"overpaymentLiabilityAccountId"), INTEREST_RECEIVABLE("receivableInterestAccountId"), FEES_RECEIVABLE(
|
||||
"receivableFeeAccountId"), PENALTIES_RECEIVABLE("receivablePenaltyAccountId"), TRANSFERS_SUSPENSE(
|
||||
"transfersInSuspenseAccountId"), PAYMENT_CHANNEL_FUND_SOURCE_MAPPING("paymentChannelToFundSourceMappings"), PAYMENT_TYPE(
|
||||
"paymentTypeId"), FEE_INCOME_ACCOUNT_MAPPING("feeToIncomeAccountMappings"), PENALTY_INCOME_ACCOUNT_MAPPING(
|
||||
"penaltyToIncomeAccountMappings"), CHARGE_ID("chargeId"), INCOME_ACCOUNT_ID("incomeAccountId");
|
||||
|
||||
private final String value;
|
||||
|
||||
|
||||
+7
@@ -69,6 +69,13 @@ public class AccountingDropdownReadPlatformServiceImpl implements AccountingDrop
|
||||
expenseAccountOptions = null;
|
||||
}
|
||||
accountOptions.put("expenseAccountOptions", expenseAccountOptions);
|
||||
|
||||
List<GLAccountData> liabilityAccountOptions = this.accountReadPlatformService
|
||||
.retrieveAllEnabledDetailGLAccounts(GLAccountType.LIABILITY);
|
||||
if (liabilityAccountOptions.isEmpty()) {
|
||||
liabilityAccountOptions = null;
|
||||
}
|
||||
accountOptions.put("liabilityAccountOptions", liabilityAccountOptions);
|
||||
return accountOptions;
|
||||
}
|
||||
|
||||
|
||||
+8
-2
@@ -27,6 +27,7 @@ public class LoanTransactionDTO {
|
||||
private final BigDecimal interest;
|
||||
private final BigDecimal fees;
|
||||
private final BigDecimal penalties;
|
||||
private final BigDecimal overPayment;
|
||||
|
||||
/*** Boolean values determines if the transaction is reversed ***/
|
||||
private final boolean reversed;
|
||||
@@ -37,8 +38,8 @@ public class LoanTransactionDTO {
|
||||
|
||||
public LoanTransactionDTO(final Long officeId, final Long paymentTypeId, final String transactionId, final Date transactionDate,
|
||||
final LoanTransactionEnumData transactionType, final BigDecimal amount, final BigDecimal principal, final BigDecimal interest,
|
||||
final BigDecimal fees, final BigDecimal penalties, final boolean reversed, final List<ChargePaymentDTO> feePayments,
|
||||
final List<ChargePaymentDTO> penaltyPayments) {
|
||||
final BigDecimal fees, final BigDecimal penalties, final BigDecimal overPayment, final boolean reversed,
|
||||
final List<ChargePaymentDTO> feePayments, final List<ChargePaymentDTO> penaltyPayments) {
|
||||
this.paymentTypeId = paymentTypeId;
|
||||
this.transactionId = transactionId;
|
||||
this.transactionDate = transactionDate;
|
||||
@@ -51,6 +52,7 @@ public class LoanTransactionDTO {
|
||||
this.transactionType = transactionType;
|
||||
this.feePayments = feePayments;
|
||||
this.penaltyPayments = penaltyPayments;
|
||||
this.overPayment = overPayment;
|
||||
this.officeId = officeId;
|
||||
}
|
||||
|
||||
@@ -90,6 +92,10 @@ public class LoanTransactionDTO {
|
||||
return this.penalties;
|
||||
}
|
||||
|
||||
public BigDecimal getOverPayment() {
|
||||
return this.overPayment;
|
||||
}
|
||||
|
||||
public boolean isReversed() {
|
||||
return this.reversed;
|
||||
}
|
||||
|
||||
+11
-5
@@ -32,6 +32,7 @@ import org.mifosplatform.accounting.journalentry.exception.JournalEntryInvalidEx
|
||||
import org.mifosplatform.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||
import org.mifosplatform.accounting.producttoaccountmapping.domain.ProductToGLAccountMapping;
|
||||
import org.mifosplatform.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||
import org.mifosplatform.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingNotFoundException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
@@ -81,11 +82,12 @@ public class AccountingProcessorHelper {
|
||||
final BigDecimal interest = (BigDecimal) map.get("interestPortion");
|
||||
final BigDecimal fees = (BigDecimal) map.get("feeChargesPortion");
|
||||
final BigDecimal penalties = (BigDecimal) map.get("penaltyChargesPortion");
|
||||
final BigDecimal overPayments = (BigDecimal) map.get("overPaymentPortion");
|
||||
final boolean reversed = (Boolean) map.get("reversed");
|
||||
final Long paymentTypeId = (Long) map.get("paymentTypeId");
|
||||
|
||||
final List<ChargePaymentDTO> feePayments = new ArrayList<ChargePaymentDTO>();
|
||||
final List<ChargePaymentDTO> penaltyPayments = new ArrayList<ChargePaymentDTO>();
|
||||
final List<ChargePaymentDTO> feePaymentDetails = new ArrayList<ChargePaymentDTO>();
|
||||
final List<ChargePaymentDTO> penaltyPaymentDetails = new ArrayList<ChargePaymentDTO>();
|
||||
// extract charge payment details (if exists)
|
||||
if (map.containsKey("loanChargesPaid")) {
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -97,15 +99,16 @@ public class AccountingProcessorHelper {
|
||||
final BigDecimal chargeAmountPaid = (BigDecimal) loanChargePaid.get("amount");
|
||||
final ChargePaymentDTO chargePaymentDTO = new ChargePaymentDTO(chargeId, loanChargeId, chargeAmountPaid);
|
||||
if (isPenalty) {
|
||||
penaltyPayments.add(chargePaymentDTO);
|
||||
penaltyPaymentDetails.add(chargePaymentDTO);
|
||||
} else {
|
||||
feePayments.add(chargePaymentDTO);
|
||||
feePaymentDetails.add(chargePaymentDTO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final LoanTransactionDTO transaction = new LoanTransactionDTO(transactionOfficeId, paymentTypeId, transactionId,
|
||||
transactionDate, transactionType, amount, principal, interest, fees, penalties, reversed, feePayments, penaltyPayments);
|
||||
transactionDate, transactionType, amount, principal, interest, fees, penalties, overPayments, reversed,
|
||||
feePaymentDetails, penaltyPaymentDetails);
|
||||
|
||||
newLoanTransactions.add(transaction);
|
||||
|
||||
@@ -513,6 +516,9 @@ public class AccountingProcessorHelper {
|
||||
}
|
||||
}
|
||||
|
||||
if (accountMapping == null) { throw new ProductToGLAccountMappingNotFoundException(PortfolioProductType.LOAN, loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.OVERPAYMENT.toString()); }
|
||||
|
||||
return accountMapping.getGlAccount();
|
||||
}
|
||||
|
||||
|
||||
+41
@@ -55,6 +55,11 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
|
||||
|| loanTransactionDTO.getTransactionType().isChargePayment()) {
|
||||
createJournalEntriesForRepayments(loanDTO, loanTransactionDTO, office);
|
||||
}
|
||||
|
||||
/** Logic for Refunds of Overpayments **/
|
||||
else if (loanTransactionDTO.getTransactionType().isRefund()) {
|
||||
createJournalEntriesForRefund(loanDTO, loanTransactionDTO, office);
|
||||
}
|
||||
/***
|
||||
* Only principal write off affects cash based accounting (interest
|
||||
* and fee write off need not be considered). Debit losses written
|
||||
@@ -103,6 +108,35 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
|
||||
isReversal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Debit loan Portfolio and credit Fund source for a Disbursement <br/>
|
||||
*
|
||||
* All debits are turned into credits and vice versa in case of disbursement
|
||||
* reversals
|
||||
*
|
||||
*
|
||||
* @param loanDTO
|
||||
* @param loanTransactionDTO
|
||||
* @param office
|
||||
*/
|
||||
private void createJournalEntriesForRefund(final LoanDTO loanDTO, final LoanTransactionDTO loanTransactionDTO, final Office office) {
|
||||
// loan properties
|
||||
final Long loanProductId = loanDTO.getLoanProductId();
|
||||
final Long loanId = loanDTO.getLoanId();
|
||||
final String currencyCode = loanDTO.getCurrencyCode();
|
||||
|
||||
// transaction properties
|
||||
final String transactionId = loanTransactionDTO.getTransactionId();
|
||||
final Date transactionDate = loanTransactionDTO.getTransactionDate();
|
||||
final BigDecimal refundAmount = loanTransactionDTO.getAmount();
|
||||
final boolean isReversal = loanTransactionDTO.isReversed();
|
||||
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
|
||||
|
||||
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode, CASH_ACCOUNTS_FOR_LOAN.OVERPAYMENT,
|
||||
CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE, loanProductId, paymentTypeId, loanId, transactionId, transactionDate, refundAmount,
|
||||
isReversal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a single Debit to fund source and multiple credits if applicable
|
||||
* (loan portfolio for principal repayments, Interest on loans for interest
|
||||
@@ -125,6 +159,7 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
|
||||
final BigDecimal interestAmount = loanTransactionDTO.getInterest();
|
||||
final BigDecimal feesAmount = loanTransactionDTO.getFees();
|
||||
final BigDecimal penaltiesAmount = loanTransactionDTO.getPenalties();
|
||||
final BigDecimal overPaymentAmount = loanTransactionDTO.getOverPayment();
|
||||
final boolean isReversal = loanTransactionDTO.isReversed();
|
||||
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
|
||||
|
||||
@@ -156,6 +191,12 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
|
||||
penaltiesAmount, isReversal, loanTransactionDTO.getPenaltyPayments());
|
||||
}
|
||||
|
||||
if (overPaymentAmount != null && !(overPaymentAmount.compareTo(BigDecimal.ZERO) == 0)) {
|
||||
totalDebitAmount = totalDebitAmount.add(overPaymentAmount);
|
||||
this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, CASH_ACCOUNTS_FOR_LOAN.OVERPAYMENT, loanProductId,
|
||||
paymentTypeId, loanId, transactionId, transactionDate, overPaymentAmount, isReversal);
|
||||
}
|
||||
|
||||
/*** create a single debit entry (or reversal) for the entire amount **/
|
||||
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE, loanProductId,
|
||||
paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount, isReversal);
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
|
||||
public class ProductToGLAccountMappingNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public ProductToGLAccountMappingNotFoundException(final PortfolioProductType type, final Long productId, final String accountType) {
|
||||
super("error.msg.productTyAccountMapping.not.found", "Mapping for product of type" + type.toString() + " with Id " + productId
|
||||
super("error.msg.productToAccountMapping.not.found", "Mapping for product of type " + type.toString() + " with Id " + productId
|
||||
+ " does not exist for an account of type " + accountType, type.toString(), productId, accountType);
|
||||
}
|
||||
}
|
||||
+5
@@ -107,6 +107,11 @@ public final class ProductToGLAccountMappingFromApiJsonDeserializer {
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue()).value(writeOffAccountId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
final Long overpaymentAccountId = this.fromApiJsonHelper.extractLongNamed(
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue()).value(overpaymentAccountId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
final Long transfersInSuspenseAccountId = this.fromApiJsonHelper.extractLongNamed(
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue())
|
||||
|
||||
+23
-8
@@ -52,6 +52,11 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
|
||||
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.EXPENSE, PortfolioProductType.LOAN);
|
||||
}
|
||||
|
||||
public void saveLoanToLiabilityAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||
final int placeHolderTypeId) {
|
||||
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.LIABILITY, PortfolioProductType.LOAN);
|
||||
}
|
||||
|
||||
/*** Set of abstractions for merging Savings Products to GL Account Mappings ***/
|
||||
public void mergeLoanToAssetAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||
@@ -71,6 +76,12 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
|
||||
PortfolioProductType.LOAN);
|
||||
}
|
||||
|
||||
public void mergeLoanToLiabilityAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes,
|
||||
GLAccountType.LIABILITY, PortfolioProductType.LOAN);
|
||||
}
|
||||
|
||||
/*** Abstractions for payments channel related to loan products ***/
|
||||
|
||||
public void savePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||
@@ -112,6 +123,8 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), element);
|
||||
final Long writeOffAccountId = this.fromApiJsonHelper.extractLongNamed(
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), element);
|
||||
final Long overPaymentAccountId = this.fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(),
|
||||
element);
|
||||
final Long transfersInSuspenseAccountId = this.fromApiJsonHelper.extractLongNamed(
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), element);
|
||||
|
||||
@@ -132,19 +145,13 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), incomeFromFeeId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), incomeFromPenaltyId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), writeOffAccountId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(), overPaymentAccountId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), transfersInSuspenseAccountId);
|
||||
break;
|
||||
//$FALL-THROUGH$
|
||||
case ACCRUAL_BASED:
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), fundAccountId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), loanPortfolioAccountId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), incomeFromInterestId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), incomeFromFeeId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), incomeFromPenaltyId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), writeOffAccountId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(), receivableInterestAccountId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), receivableFeeAccountId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(), receivablePenaltyAccountId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), transfersInSuspenseAccountId);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -187,6 +194,10 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
|
||||
mergeLoanToExpenseAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(),
|
||||
loanProductId, CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue(),
|
||||
CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.toString(), changes);
|
||||
|
||||
// liabilities
|
||||
mergeLoanToLiabilityAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(), loanProductId,
|
||||
CASH_ACCOUNTS_FOR_LOAN.OVERPAYMENT.getValue(), CASH_ACCOUNTS_FOR_LOAN.OVERPAYMENT.toString(), changes);
|
||||
break;
|
||||
case ACCRUAL_BASED:
|
||||
// assets (including receivables)
|
||||
@@ -221,6 +232,10 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
|
||||
mergeLoanToExpenseAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(),
|
||||
loanProductId, ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue(),
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.toString(), changes);
|
||||
|
||||
// liabilities
|
||||
mergeLoanToLiabilityAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(), loanProductId,
|
||||
CASH_ACCOUNTS_FOR_LOAN.OVERPAYMENT.getValue(), CASH_ACCOUNTS_FOR_LOAN.OVERPAYMENT.toString(), changes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -106,6 +106,8 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
||||
accountMappingDetails.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), glAccountId);
|
||||
} else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF)) {
|
||||
accountMappingDetails.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), glAccountId);
|
||||
} else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.OVERPAYMENT)) {
|
||||
accountMappingDetails.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(), glAccountId);
|
||||
}
|
||||
}
|
||||
} else if (AccountingRuleType.ACCRUAL_BASED.getValue().equals(accountingType)) {
|
||||
@@ -126,6 +128,8 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
||||
accountMappingDetails.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), glAccountId);
|
||||
} else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO)) {
|
||||
accountMappingDetails.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), glAccountId);
|
||||
} else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.OVERPAYMENT)) {
|
||||
accountMappingDetails.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(), glAccountId);
|
||||
} else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.TRANSFERS_SUSPENSE)) {
|
||||
accountMappingDetails.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), glAccountId);
|
||||
} else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF)) {
|
||||
|
||||
+10
-3
@@ -79,9 +79,11 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
|
||||
CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue());
|
||||
|
||||
// expenses
|
||||
this.loanProductToGLAccountMappingHelper.saveLoanToExpenseAccountMapping(element,
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), loanProductId,
|
||||
CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue());
|
||||
this.loanProductToGLAccountMappingHelper
|
||||
.saveLoanToLiabilityAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(), loanProductId,
|
||||
CASH_ACCOUNTS_FOR_LOAN.OVERPAYMENT.getValue());
|
||||
|
||||
// liabilities
|
||||
|
||||
// advanced accounting mappings
|
||||
this.loanProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, loanProductId, null);
|
||||
@@ -125,6 +127,11 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue());
|
||||
|
||||
// liabilities
|
||||
this.loanProductToGLAccountMappingHelper.saveLoanToLiabilityAccountMapping(element,
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.OVERPAYMENT.getValue());
|
||||
|
||||
// advanced accounting mappings
|
||||
this.loanProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, loanProductId, null);
|
||||
this.loanProductToGLAccountMappingHelper.saveChargesToIncomeAccountMappings(command, element, loanProductId, null);
|
||||
|
||||
+14
-11
@@ -35,6 +35,7 @@ public class LoanTransactionData {
|
||||
private final BigDecimal interestPortion;
|
||||
private final BigDecimal feeChargesPortion;
|
||||
private final BigDecimal penaltyChargesPortion;
|
||||
private final BigDecimal overpaymentPortion;
|
||||
private final String externalId;
|
||||
private final AccountTransferData transfer;
|
||||
|
||||
@@ -46,23 +47,24 @@ public class LoanTransactionData {
|
||||
return new LoanTransactionData(loanTransactionData.id, loanTransactionData.officeId, loanTransactionData.officeName,
|
||||
loanTransactionData.type, loanTransactionData.paymentDetailData, loanTransactionData.currency, loanTransactionData.date,
|
||||
loanTransactionData.amount, loanTransactionData.principalPortion, loanTransactionData.interestPortion,
|
||||
loanTransactionData.feeChargesPortion, loanTransactionData.penaltyChargesPortion, paymentTypeOptions,
|
||||
loanTransactionData.externalId, loanTransactionData.transfer);
|
||||
loanTransactionData.feeChargesPortion, loanTransactionData.penaltyChargesPortion, loanTransactionData.overpaymentPortion,
|
||||
paymentTypeOptions, loanTransactionData.externalId, loanTransactionData.transfer);
|
||||
}
|
||||
|
||||
public LoanTransactionData(final Long id, final Long officeId, final String officeName, final LoanTransactionEnumData transactionType,
|
||||
final PaymentDetailData paymentDetailData, final CurrencyData currency, final LocalDate date, final BigDecimal amount,
|
||||
final BigDecimal principalPortion, final BigDecimal interestPortion, final BigDecimal feeChargesPortion,
|
||||
final BigDecimal penaltyChargesPortion, final String externalId, final AccountTransferData transfer) {
|
||||
this(id, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, principalPortion, interestPortion,
|
||||
feeChargesPortion, penaltyChargesPortion, null, externalId, transfer);
|
||||
}
|
||||
|
||||
public LoanTransactionData(final Long id, final Long officeId, final String officeName, final LoanTransactionEnumData transactionType,
|
||||
final PaymentDetailData paymentDetailData, final CurrencyData currency, final LocalDate date, final BigDecimal amount,
|
||||
final BigDecimal principalPortion, final BigDecimal interestPortion, final BigDecimal feeChargesPortion,
|
||||
final BigDecimal penaltyChargesPortion, final Collection<CodeValueData> paymentTypeOptions, final String externalId,
|
||||
final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion, final String externalId,
|
||||
final AccountTransferData transfer) {
|
||||
this(id, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, principalPortion, interestPortion,
|
||||
feeChargesPortion, penaltyChargesPortion, overpaymentPortion, null, externalId, transfer);
|
||||
}
|
||||
|
||||
public LoanTransactionData(final Long id, final Long officeId, final String officeName, final LoanTransactionEnumData transactionType,
|
||||
final PaymentDetailData paymentDetailData, final CurrencyData currency, final LocalDate date, final BigDecimal amount,
|
||||
final BigDecimal principalPortion, final BigDecimal interestPortion, final BigDecimal feeChargesPortion,
|
||||
final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion,
|
||||
final Collection<CodeValueData> paymentTypeOptions, final String externalId, final AccountTransferData transfer) {
|
||||
this.id = id;
|
||||
this.officeId = officeId;
|
||||
this.officeName = officeName;
|
||||
@@ -78,6 +80,7 @@ public class LoanTransactionData {
|
||||
this.paymentTypeOptions = paymentTypeOptions;
|
||||
this.externalId = externalId;
|
||||
this.transfer = transfer;
|
||||
this.overpaymentPortion = overpaymentPortion;
|
||||
}
|
||||
|
||||
public LocalDate dateOf() {
|
||||
|
||||
+24
-8
@@ -82,6 +82,9 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
@Column(name = "penalty_charges_portion_derived", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal penaltyChargesPortion;
|
||||
|
||||
@Column(name = "overpayment_portion_derived", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal overPaymentPortion;
|
||||
|
||||
@Column(name = "is_reversed", nullable = false)
|
||||
private boolean reversed;
|
||||
|
||||
@@ -133,21 +136,21 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
return new LoanTransaction(loan, office, LoanTransactionType.INITIATE_TRANSFER.getValue(), transferDate.toDateMidnight().toDate(),
|
||||
loan.getSummary().getTotalOutstanding(), loan.getSummary().getTotalPrincipalOutstanding(), loan.getSummary()
|
||||
.getTotalInterestOutstanding(), loan.getSummary().getTotalFeeChargesOutstanding(), loan.getSummary()
|
||||
.getTotalPenaltyChargesOutstanding(), false, null);
|
||||
.getTotalPenaltyChargesOutstanding(), null, false, null);
|
||||
}
|
||||
|
||||
public static LoanTransaction approveTransfer(final Office office, final Loan loan, final LocalDate transferDate) {
|
||||
return new LoanTransaction(loan, office, LoanTransactionType.APPROVE_TRANSFER.getValue(), transferDate.toDateMidnight().toDate(),
|
||||
loan.getSummary().getTotalOutstanding(), loan.getSummary().getTotalPrincipalOutstanding(), loan.getSummary()
|
||||
.getTotalInterestOutstanding(), loan.getSummary().getTotalFeeChargesOutstanding(), loan.getSummary()
|
||||
.getTotalPenaltyChargesOutstanding(), false, null);
|
||||
.getTotalPenaltyChargesOutstanding(), null, false, null);
|
||||
}
|
||||
|
||||
public static LoanTransaction withdrawTransfer(final Office office, final Loan loan, final LocalDate transferDate) {
|
||||
return new LoanTransaction(loan, office, LoanTransactionType.WITHDRAW_TRANSFER.getValue(), transferDate.toDateMidnight().toDate(),
|
||||
loan.getSummary().getTotalOutstanding(), loan.getSummary().getTotalPrincipalOutstanding(), loan.getSummary()
|
||||
.getTotalInterestOutstanding(), loan.getSummary().getTotalFeeChargesOutstanding(), loan.getSummary()
|
||||
.getTotalPenaltyChargesOutstanding(), false, null);
|
||||
.getTotalPenaltyChargesOutstanding(), null, false, null);
|
||||
}
|
||||
|
||||
public static LoanTransaction refund(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||
@@ -158,8 +161,8 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
public static LoanTransaction copyTransactionProperties(final LoanTransaction loanTransaction) {
|
||||
return new LoanTransaction(loanTransaction.loan, loanTransaction.office, loanTransaction.typeOf, loanTransaction.dateOf,
|
||||
loanTransaction.amount, loanTransaction.principalPortion, loanTransaction.interestPortion,
|
||||
loanTransaction.feeChargesPortion, loanTransaction.penaltyChargesPortion, loanTransaction.reversed,
|
||||
loanTransaction.paymentDetail);
|
||||
loanTransaction.feeChargesPortion, loanTransaction.penaltyChargesPortion, loanTransaction.overPaymentPortion,
|
||||
loanTransaction.reversed, loanTransaction.paymentDetail);
|
||||
}
|
||||
|
||||
public static LoanTransaction applyLoanCharge(final Loan loan, final Office office, final Money amount, final LocalDate applyDate,
|
||||
@@ -176,13 +179,15 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
&& (loanTransaction.getPrincipalPortion(currency).isEqualTo(newLoanTransaction.getPrincipalPortion(currency)))
|
||||
&& (loanTransaction.getInterestPortion(currency).isEqualTo(newLoanTransaction.getInterestPortion(currency)))
|
||||
&& (loanTransaction.getFeeChargesPortion(currency).isEqualTo(newLoanTransaction.getFeeChargesPortion(currency)))
|
||||
&& (loanTransaction.getPenaltyChargesPortion(currency).isEqualTo(newLoanTransaction.getPenaltyChargesPortion(currency)))) { return true; }
|
||||
&& (loanTransaction.getPenaltyChargesPortion(currency).isEqualTo(newLoanTransaction.getPenaltyChargesPortion(currency)))
|
||||
&& (loanTransaction.getOverPaymentPortion(currency).isEqualTo(newLoanTransaction.getOverPaymentPortion(currency)))) { return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
private LoanTransaction(final Loan loan, final Office office, final Integer typeOf, final Date dateOf, final BigDecimal amount,
|
||||
final BigDecimal principalPortion, final BigDecimal interestPortion, final BigDecimal feeChargesPortion,
|
||||
final BigDecimal penaltyChargesPortion, final boolean reversed, final PaymentDetail paymentDetail) {
|
||||
final BigDecimal penaltyChargesPortion, final BigDecimal overPaymentPortion, final boolean reversed,
|
||||
final PaymentDetail paymentDetail) {
|
||||
super();
|
||||
this.loan = loan;
|
||||
this.typeOf = typeOf;
|
||||
@@ -192,6 +197,7 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
this.interestPortion = interestPortion;
|
||||
this.feeChargesPortion = feeChargesPortion;
|
||||
this.penaltyChargesPortion = penaltyChargesPortion;
|
||||
this.overPaymentPortion = overPaymentPortion;
|
||||
this.reversed = reversed;
|
||||
this.paymentDetail = paymentDetail;
|
||||
this.office = office;
|
||||
@@ -274,6 +280,11 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
.plus(getPenaltyChargesPortion(currency)).getAmount();
|
||||
}
|
||||
|
||||
public void updateOverPayments(final Money overPayment) {
|
||||
final MonetaryCurrency currency = overPayment.getCurrency();
|
||||
this.overPaymentPortion = defaultToNullIfZero(getOverPaymentPortion(currency).plus(overPayment).getAmount());
|
||||
}
|
||||
|
||||
public Money getPrincipalPortion(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.principalPortion);
|
||||
}
|
||||
@@ -294,6 +305,10 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
return Money.of(currency, this.penaltyChargesPortion);
|
||||
}
|
||||
|
||||
public Money getOverPaymentPortion(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.overPaymentPortion);
|
||||
}
|
||||
|
||||
public Money getAmount(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.amount);
|
||||
}
|
||||
@@ -425,7 +440,7 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
}
|
||||
return new LoanTransactionData(getId(), this.office.getId(), this.office.getName(), transactionType, paymentDetailData,
|
||||
currencyData, getTransactionDate(), this.amount, this.principalPortion, this.interestPortion, this.feeChargesPortion,
|
||||
this.penaltyChargesPortion, this.externalId, transfer);
|
||||
this.penaltyChargesPortion, this.overPaymentPortion, this.externalId, transfer);
|
||||
}
|
||||
|
||||
public Map<String, Object> toMapData(final CurrencyData currencyData) {
|
||||
@@ -444,6 +459,7 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
thisTransactionData.put("interestPortion", this.interestPortion);
|
||||
thisTransactionData.put("feeChargesPortion", this.feeChargesPortion);
|
||||
thisTransactionData.put("penaltyChargesPortion", this.penaltyChargesPortion);
|
||||
thisTransactionData.put("overPaymentPortion", this.overPaymentPortion);
|
||||
|
||||
if (this.paymentDetail != null) {
|
||||
thisTransactionData.put("paymentTypeId", this.paymentDetail.getPaymentType().getId());
|
||||
|
||||
+1
@@ -186,6 +186,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
|
||||
if (transactionAmountUnprocessed.isGreaterThanZero()) {
|
||||
onLoanOverpayment(loanTransaction, transactionAmountUnprocessed);
|
||||
loanTransaction.updateOverPayments(transactionAmountUnprocessed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-5
@@ -330,7 +330,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final Collection<CodeValueData> paymentOptions = this.codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(PaymentDetailConstants.paymentTypeCodeName);
|
||||
return new LoanTransactionData(null, null, null, transactionType, null, currencyData, earliestUnpaidInstallmentDate,
|
||||
possibleNextRepaymentAmount.getAmount(), null, null, null, null, paymentOptions, null, null);
|
||||
possibleNextRepaymentAmount.getAmount(), null, null, null, null, null, paymentOptions, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -354,7 +354,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
|
||||
final BigDecimal amount = waiveOfInterest.getAmount(currency).getAmount();
|
||||
return new LoanTransactionData(null, null, null, transactionType, null, currencyData, waiveOfInterest.getTransactionDate(), amount,
|
||||
null, null, null, null, null, null);
|
||||
null, null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -364,7 +364,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
|
||||
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.WRITEOFF);
|
||||
return new LoanTransactionData(null, null, null, transactionType, null, null, DateUtils.getLocalDateOfTenant(), null, null, null,
|
||||
null, null, null, null);
|
||||
null, null, null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -375,7 +375,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final Collection<CodeValueData> paymentOptions = this.codeValueReadPlatformService
|
||||
.retrieveCodeValuesByCode(PaymentDetailConstants.paymentTypeCodeName);
|
||||
return new LoanTransactionData(null, null, null, transactionType, null, null, loan.getExpectedDisbursedOnLocalDate(), null, null,
|
||||
null, null, null, paymentOptions, null, null);
|
||||
null, null, null, null, paymentOptions, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -861,6 +861,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
return " tr.id as id, tr.transaction_type_enum as transactionType, tr.transaction_date as `date`, tr.amount as total, "
|
||||
+ " tr.principal_portion_derived as principal, tr.interest_portion_derived as interest, "
|
||||
+ " tr.fee_charges_portion_derived as fees, tr.penalty_charges_portion_derived as penalties, "
|
||||
+ " tr.overpayment_portion_derived as overpayment, "
|
||||
+ " pd.payment_type_cv_id as paymentType,pd.account_number as accountNumber,pd.check_number as checkNumber, "
|
||||
+ " pd.receipt_number as receiptNumber, pd.bank_number as bankNumber,pd.routing_code as routingCode, "
|
||||
+ " l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf, rc.`name` as currencyName, "
|
||||
@@ -920,6 +921,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final BigDecimal interestPortion = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interest");
|
||||
final BigDecimal feeChargesPortion = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "fees");
|
||||
final BigDecimal penaltyChargesPortion = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "penalties");
|
||||
final BigDecimal overPaymentPortion = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "overpayment");
|
||||
final String externalId = rs.getString("externalId");
|
||||
|
||||
AccountTransferData transfer = null;
|
||||
@@ -944,7 +946,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
}
|
||||
|
||||
return new LoanTransactionData(id, officeId, officeName, transactionType, paymentDetailData, currencyData, date, totalAmount,
|
||||
principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion, externalId, transfer);
|
||||
principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion, overPaymentPortion, externalId, transfer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-2
@@ -48,8 +48,8 @@ public final class LoanProductDataValidator {
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.FEE_INCOME_ACCOUNT_MAPPING.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTY_INCOME_ACCOUNT_MAPPING.getValue()));
|
||||
@@ -282,6 +282,11 @@ public final class LoanProductDataValidator {
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue()).value(writeOffAccountId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
final Long overpaymentAccountId = this.fromApiJsonHelper.extractLongNamed(
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue()).value(overpaymentAccountId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
validatePaymentChannelFundSourceMappings(baseDataValidator, element);
|
||||
validateChargeToIncomeAccountMappings(baseDataValidator, element);
|
||||
|
||||
@@ -520,6 +525,11 @@ public final class LoanProductDataValidator {
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue()).value(writeOffAccountId)
|
||||
.ignoreIfNull().integerGreaterThanZero();
|
||||
|
||||
final Long overpaymentAccountId = this.fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(),
|
||||
element);
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue()).value(overpaymentAccountId)
|
||||
.ignoreIfNull().integerGreaterThanZero();
|
||||
|
||||
final Long receivableInterestAccountId = this.fromApiJsonHelper.extractLongNamed(
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue())
|
||||
|
||||
Reference in New Issue
Block a user