Merge pull request #854 from vishwasbabu/develop
MIFOSX-865: initial work around adding support for accrual accounting
This commit is contained in:
+2
-1
@@ -12,7 +12,8 @@ public enum AccountingRuleType {
|
||||
|
||||
NONE(1, "accountingRuleType.none"), //
|
||||
CASH_BASED(2, "accountingRuleType.cash"), //
|
||||
ACCRUAL_BASED(3, "accountingRuleType.accrual");
|
||||
ACCRUAL_PERIODIC(3, "accountingRuleType.accrual.periodic"), //
|
||||
ACCRUAL_UPFRONT(4, "accountingRuleType.accrual.upfront"); //
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
+6
-5
@@ -190,16 +190,16 @@ public final class ProductToGLAccountMappingFromApiJsonDeserializer {
|
||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), element);
|
||||
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.OVERDRAFT_PORTFOLIO_CONTROL.getValue())
|
||||
.value(overdraftAccount).notNull().integerGreaterThanZero();
|
||||
|
||||
|
||||
final Long incomeFromInterest = this.fromApiJsonHelper.extractLongNamed(
|
||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_INTEREST.getValue(), element);
|
||||
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_INTEREST.getValue())
|
||||
.value(incomeFromInterest).notNull().integerGreaterThanZero();
|
||||
|
||||
|
||||
final Long writtenOff = this.fromApiJsonHelper.extractLongNamed(
|
||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), element);
|
||||
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue())
|
||||
.value(writtenOff).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue()).value(writtenOff)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
}
|
||||
|
||||
@@ -211,7 +211,8 @@ public final class ProductToGLAccountMappingFromApiJsonDeserializer {
|
||||
}
|
||||
|
||||
private boolean isAccrualBasedAccounting(final Integer accountingRuleType) {
|
||||
return AccountingRuleType.ACCRUAL_BASED.getValue().equals(accountingRuleType);
|
||||
return AccountingRuleType.ACCRUAL_PERIODIC.getValue().equals(accountingRuleType)
|
||||
|| AccountingRuleType.ACCRUAL_UPFRONT.getValue().equals(accountingRuleType);
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
|
||||
+42
-14
@@ -139,25 +139,51 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
|
||||
case NONE:
|
||||
break;
|
||||
case CASH_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.OVERPAYMENT.getValue(), overPaymentAccountId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), transfersInSuspenseAccountId);
|
||||
//$FALL-THROUGH$
|
||||
case ACCRUAL_BASED:
|
||||
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);
|
||||
populateChangesForCashBasedAccounting(changes, fundAccountId, loanPortfolioAccountId, incomeFromInterestId,
|
||||
incomeFromFeeId, incomeFromPenaltyId, writeOffAccountId, overPaymentAccountId, transfersInSuspenseAccountId);
|
||||
break;
|
||||
case ACCRUAL_PERIODIC:
|
||||
populateChangesForAccrualBasedAccounting(changes, fundAccountId, loanPortfolioAccountId, incomeFromInterestId,
|
||||
incomeFromFeeId, incomeFromPenaltyId, writeOffAccountId, overPaymentAccountId, transfersInSuspenseAccountId,
|
||||
receivableInterestAccountId, receivableFeeAccountId, receivablePenaltyAccountId);
|
||||
break;
|
||||
case ACCRUAL_UPFRONT:
|
||||
populateChangesForAccrualBasedAccounting(changes, fundAccountId, loanPortfolioAccountId, incomeFromInterestId,
|
||||
incomeFromFeeId, incomeFromPenaltyId, writeOffAccountId, overPaymentAccountId, transfersInSuspenseAccountId,
|
||||
receivableInterestAccountId, receivableFeeAccountId, receivablePenaltyAccountId);
|
||||
break;
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
private void populateChangesForAccrualBasedAccounting(final Map<String, Object> changes, final Long fundAccountId,
|
||||
final Long loanPortfolioAccountId, final Long incomeFromInterestId, final Long incomeFromFeeId, final Long incomeFromPenaltyId,
|
||||
final Long writeOffAccountId, final Long overPaymentAccountId, final Long transfersInSuspenseAccountId,
|
||||
final Long receivableInterestAccountId, final Long receivableFeeAccountId, final Long receivablePenaltyAccountId) {
|
||||
|
||||
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);
|
||||
|
||||
populateChangesForCashBasedAccounting(changes, fundAccountId, loanPortfolioAccountId, incomeFromInterestId, incomeFromFeeId,
|
||||
incomeFromPenaltyId, writeOffAccountId, overPaymentAccountId, transfersInSuspenseAccountId);
|
||||
|
||||
}
|
||||
|
||||
private void populateChangesForCashBasedAccounting(final Map<String, Object> changes, final Long fundAccountId,
|
||||
final Long loanPortfolioAccountId, final Long incomeFromInterestId, final Long incomeFromFeeId, final Long incomeFromPenaltyId,
|
||||
final Long writeOffAccountId, final Long overPaymentAccountId, final Long transfersInSuspenseAccountId) {
|
||||
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.OVERPAYMENT.getValue(), overPaymentAccountId);
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), transfersInSuspenseAccountId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Examines and updates each account mapping for given loan product with
|
||||
* changes passed in from the Json element
|
||||
@@ -199,7 +225,9 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
|
||||
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:
|
||||
case ACCRUAL_UPFRONT:
|
||||
// fall through to periodic accrual
|
||||
case ACCRUAL_PERIODIC:
|
||||
// assets (including receivables)
|
||||
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE.toString(), changes);
|
||||
|
||||
+27
-28
@@ -44,14 +44,13 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
||||
private static final class ProductToGLAccountMappingMapper implements RowMapper<Map<String, Object>> {
|
||||
|
||||
public String schema() {
|
||||
return " mapping.id as id, mapping.gl_account_id as glAccountId,glaccount.name as name,glaccount.gl_code as code,"
|
||||
return " mapping.id as id, mapping.gl_account_id as glAccountId,glaccount.name as name,glaccount.gl_code as code,"
|
||||
+ " mapping.product_id as productId, mapping.product_type as productType,mapping.financial_account_type as financialAccountType, "
|
||||
+ " mapping.payment_type as paymentTypeId,cv.code_value codeValue, mapping.charge_id as chargeId, charge.is_penalty as penalty, "
|
||||
+ " charge.name as chargeName "
|
||||
+ " from acc_product_mapping mapping left join m_charge charge on mapping.charge_id=charge.id "
|
||||
+ " left join acc_gl_account as glaccount on mapping.gl_account_id = glaccount.id"
|
||||
+ " left join m_code_value cv on mapping.payment_type=cv.id"
|
||||
+ " where mapping.product_type= ? ";
|
||||
+ " left join m_code_value cv on mapping.payment_type=cv.id" + " where mapping.product_type= ? ";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,7 +68,7 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
||||
final String glCode = rs.getString("code");
|
||||
final String chargeName = rs.getString("chargeName");
|
||||
final Boolean penalty = rs.getBoolean("penalty");
|
||||
|
||||
|
||||
final Map<String, Object> loanProductToGLAccountMap = new LinkedHashMap<String, Object>(5);
|
||||
loanProductToGLAccountMap.put("id", id);
|
||||
loanProductToGLAccountMap.put("glAccountId", glAccountId);
|
||||
@@ -77,7 +76,7 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
||||
loanProductToGLAccountMap.put("productType", productType);
|
||||
loanProductToGLAccountMap.put("financialAccountType", financialAccountType);
|
||||
loanProductToGLAccountMap.put("paymentTypeId", paymentTypeId);
|
||||
loanProductToGLAccountMap.put("paymentTypeValue",paymentTypeValue);
|
||||
loanProductToGLAccountMap.put("paymentTypeValue", paymentTypeValue);
|
||||
loanProductToGLAccountMap.put("chargeId", chargeId);
|
||||
loanProductToGLAccountMap.put("chargeName", chargeName);
|
||||
loanProductToGLAccountMap.put("penalty", penalty);
|
||||
@@ -106,9 +105,9 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
||||
final CASH_ACCOUNTS_FOR_LOAN glAccountForLoan = CASH_ACCOUNTS_FOR_LOAN.fromInt(financialAccountType);
|
||||
|
||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
||||
final String glAccountName = (String)productToGLAccountMap.get("glAccountName");
|
||||
final String glCode = (String)productToGLAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData(glAccountId, glAccountName, glCode);
|
||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData(glAccountId, glAccountName, glCode);
|
||||
|
||||
if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE)) {
|
||||
accountMappingDetails.put(LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.FUND_SOURCE.getValue(), gLAccountData);
|
||||
@@ -128,16 +127,17 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
||||
accountMappingDetails.put(LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.OVERPAYMENT.getValue(), gLAccountData);
|
||||
}
|
||||
}
|
||||
} else if (AccountingRuleType.ACCRUAL_BASED.getValue().equals(accountingType)) {
|
||||
} else if (AccountingRuleType.ACCRUAL_UPFRONT.getValue().equals(accountingType)
|
||||
|| AccountingRuleType.ACCRUAL_PERIODIC.getValue().equals(accountingType)) {
|
||||
|
||||
for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {
|
||||
final Integer financialAccountType = (Integer) productToGLAccountMap.get("financialAccountType");
|
||||
final ACCRUAL_ACCOUNTS_FOR_LOAN glAccountForLoan = ACCRUAL_ACCOUNTS_FOR_LOAN.fromInt(financialAccountType);
|
||||
|
||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
||||
final String glAccountName = (String)productToGLAccountMap.get("glAccountName");
|
||||
final String glCode = (String)productToGLAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData(glAccountId, glAccountName, glCode);
|
||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData(glAccountId, glAccountName, glCode);
|
||||
|
||||
if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE)) {
|
||||
accountMappingDetails.put(LOAN_PRODUCT_ACCOUNTING_DATA_PARAMS.FUND_SOURCE.getValue(), gLAccountData);
|
||||
@@ -187,10 +187,9 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
||||
final CASH_ACCOUNTS_FOR_SAVINGS glAccountForSavings = CASH_ACCOUNTS_FOR_SAVINGS.fromInt(financialAccountType);
|
||||
|
||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
||||
final String glAccountName = (String)productToGLAccountMap.get("glAccountName");
|
||||
final String glCode = (String)productToGLAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData(glAccountId, glAccountName, glCode);
|
||||
|
||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData(glAccountId, glAccountName, glCode);
|
||||
|
||||
if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_REFERENCE)) {
|
||||
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.SAVINGS_REFERENCE.getValue(), gLAccountData);
|
||||
@@ -206,9 +205,9 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
||||
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.INTEREST_ON_SAVINGS.getValue(), gLAccountData);
|
||||
} else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.OVERDRAFT_PORTFOLIO_CONTROL)) {
|
||||
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), gLAccountData);
|
||||
}else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.LOSSES_WRITTEN_OFF)) {
|
||||
} else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.LOSSES_WRITTEN_OFF)) {
|
||||
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.LOSSES_WRITTEN_OFF.getValue(), gLAccountData);
|
||||
}else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_INTEREST)) {
|
||||
} else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_INTEREST)) {
|
||||
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_DATA_PARAMS.INCOME_FROM_INTEREST.getValue(), gLAccountData);
|
||||
}
|
||||
}
|
||||
@@ -245,14 +244,14 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
||||
paymentTypeToGLAccountMappers = new ArrayList<PaymentTypeToGLAccountMapper>();
|
||||
}
|
||||
final Long paymentTypeId = (Long) productToGLAccountMap.get("paymentTypeId");
|
||||
final String paymentTypeValue = (String)productToGLAccountMap.get("paymentTypeValue");
|
||||
final String paymentTypeValue = (String) productToGLAccountMap.get("paymentTypeValue");
|
||||
final CodeValueData codeValueData = CodeValueData.instance(paymentTypeId, paymentTypeValue);
|
||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
||||
final String glAccountName = (String)productToGLAccountMap.get("glAccountName");
|
||||
final String glCode = (String)productToGLAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData(glAccountId, glAccountName, glCode);
|
||||
|
||||
final PaymentTypeToGLAccountMapper paymentTypeToGLAccountMapper = new PaymentTypeToGLAccountMapper(codeValueData,gLAccountData);
|
||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData(glAccountId, glAccountName, glCode);
|
||||
|
||||
final PaymentTypeToGLAccountMapper paymentTypeToGLAccountMapper = new PaymentTypeToGLAccountMapper(codeValueData, gLAccountData);
|
||||
paymentTypeToGLAccountMappers.add(paymentTypeToGLAccountMapper);
|
||||
}
|
||||
return paymentTypeToGLAccountMappers;
|
||||
@@ -296,12 +295,12 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
||||
chargeToGLAccountMappers = new ArrayList<ChargeToGLAccountMapper>();
|
||||
}
|
||||
final Long glAccountId = (Long) chargeToIncomeAccountMap.get("glAccountId");
|
||||
final String glAccountName = (String)chargeToIncomeAccountMap.get("glAccountName");
|
||||
final String glCode = (String)chargeToIncomeAccountMap.get("glCode");
|
||||
final String glAccountName = (String) chargeToIncomeAccountMap.get("glAccountName");
|
||||
final String glCode = (String) chargeToIncomeAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData(glAccountId, glAccountName, glCode);
|
||||
final Long chargeId = (Long) chargeToIncomeAccountMap.get("chargeId");
|
||||
final String chargeName = (String)chargeToIncomeAccountMap.get("chargeName");
|
||||
final Boolean penalty1 = (Boolean)chargeToIncomeAccountMap.get("penalty");
|
||||
final String chargeName = (String) chargeToIncomeAccountMap.get("chargeName");
|
||||
final Boolean penalty1 = (Boolean) chargeToIncomeAccountMap.get("penalty");
|
||||
final ChargeData chargeData = ChargeData.lookup(chargeId, chargeName, penalty1);
|
||||
final ChargeToGLAccountMapper chargeToGLAccountMapper = new ChargeToGLAccountMapper(chargeData, gLAccountData);
|
||||
chargeToGLAccountMappers.add(chargeToGLAccountMapper);
|
||||
|
||||
+6
-7
@@ -92,8 +92,9 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
|
||||
this.loanProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, loanProductId, null);
|
||||
this.loanProductToGLAccountMappingHelper.saveChargesToIncomeAccountMappings(command, element, loanProductId, null);
|
||||
break;
|
||||
case ACCRUAL_BASED:
|
||||
|
||||
case ACCRUAL_UPFRONT:
|
||||
// Fall Through
|
||||
case ACCRUAL_PERIODIC:
|
||||
// assets (including receivables)
|
||||
this.loanProductToGLAccountMappingHelper.saveLoanToAssetAccountMapping(element,
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), loanProductId,
|
||||
@@ -170,17 +171,16 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
|
||||
this.savingsProductToGLAccountMappingHelper.saveSavingsToIncomeAccountMapping(element,
|
||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), savingProductId,
|
||||
CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_PENALTIES.getValue());
|
||||
|
||||
|
||||
this.savingsProductToGLAccountMappingHelper.saveSavingsToIncomeAccountMapping(element,
|
||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_INTEREST.getValue(), savingProductId,
|
||||
CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_INTEREST.getValue());
|
||||
|
||||
|
||||
// expenses
|
||||
this.savingsProductToGLAccountMappingHelper.saveSavingsToExpenseAccountMapping(element,
|
||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), savingProductId,
|
||||
CASH_ACCOUNTS_FOR_SAVINGS.INTEREST_ON_SAVINGS.getValue());
|
||||
|
||||
|
||||
this.savingsProductToGLAccountMappingHelper.saveSavingsToExpenseAccountMapping(element,
|
||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), savingProductId,
|
||||
CASH_ACCOUNTS_FOR_SAVINGS.LOSSES_WRITTEN_OFF.getValue());
|
||||
@@ -197,8 +197,7 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
|
||||
this.savingsProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, savingProductId, null);
|
||||
this.savingsProductToGLAccountMappingHelper.saveChargesToIncomeAccountMappings(command, element, savingProductId, null);
|
||||
break;
|
||||
/*** Do not have accrual based accounting for now ***/
|
||||
case ACCRUAL_BASED:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+15
-7
@@ -124,10 +124,10 @@ public class SavingsProductToGLAccountMappingHelper extends ProductToGLAccountMa
|
||||
element);
|
||||
final Long transfersInSuspenseAccountId = this.fromApiJsonHelper.extractLongNamed(
|
||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), element);
|
||||
final Long overdraftControlId = this.fromApiJsonHelper.extractLongNamed(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
|
||||
element);
|
||||
final Long incomeFromInterest = this.fromApiJsonHelper.extractLongNamed(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_INTEREST.getValue(),
|
||||
element);
|
||||
final Long overdraftControlId = this.fromApiJsonHelper.extractLongNamed(
|
||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), element);
|
||||
final Long incomeFromInterest = this.fromApiJsonHelper.extractLongNamed(
|
||||
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_INTEREST.getValue(), element);
|
||||
final Long writeOffId = this.fromApiJsonHelper.extractLongNamed(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(),
|
||||
element);
|
||||
switch (accountingRuleType) {
|
||||
@@ -144,7 +144,11 @@ public class SavingsProductToGLAccountMappingHelper extends ProductToGLAccountMa
|
||||
changes.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_INTEREST.getValue(), incomeFromInterest);
|
||||
changes.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), writeOffId);
|
||||
break;
|
||||
case ACCRUAL_BASED:
|
||||
case ACCRUAL_PERIODIC:
|
||||
break;
|
||||
case ACCRUAL_UPFRONT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return changes;
|
||||
@@ -169,7 +173,7 @@ public class SavingsProductToGLAccountMappingHelper extends ProductToGLAccountMa
|
||||
mergeSavingsToAssetAccountMappingChanges(element, SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(),
|
||||
savingsProductId, CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_REFERENCE.getValue(),
|
||||
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_REFERENCE.toString(), changes);
|
||||
|
||||
|
||||
mergeSavingsToAssetAccountMappingChanges(element, SAVINGS_PRODUCT_ACCOUNTING_PARAMS.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
|
||||
savingsProductId, CASH_ACCOUNTS_FOR_SAVINGS.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
|
||||
CASH_ACCOUNTS_FOR_SAVINGS.OVERDRAFT_PORTFOLIO_CONTROL.toString(), changes);
|
||||
@@ -203,7 +207,11 @@ public class SavingsProductToGLAccountMappingHelper extends ProductToGLAccountMa
|
||||
savingsProductId, CASH_ACCOUNTS_FOR_SAVINGS.TRANSFERS_SUSPENSE.getValue(),
|
||||
CASH_ACCOUNTS_FOR_SAVINGS.TRANSFERS_SUSPENSE.toString(), changes);
|
||||
break;
|
||||
case ACCRUAL_BASED:
|
||||
case ACCRUAL_PERIODIC:
|
||||
break;
|
||||
case ACCRUAL_UPFRONT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -3238,7 +3238,8 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
accountingBridgeData.put("currency", currencyData);
|
||||
accountingBridgeData.put("calculatedInterest", this.summary.getTotalInterestCharged());
|
||||
accountingBridgeData.put("cashBasedAccountingEnabled", isCashBasedAccountingEnabledOnLoanProduct());
|
||||
accountingBridgeData.put("accrualBasedAccountingEnabled", isAccrualBasedAccountingEnabledOnLoanProduct());
|
||||
accountingBridgeData.put("upfrontAccrualBasedAccountingEnabled", isAccrualBasedAccountingEnabledOnLoanProduct());
|
||||
accountingBridgeData.put("periodicAccrualBasedAccountingEnabled", isAccrualBasedAccountingEnabledOnLoanProduct());
|
||||
|
||||
final List<Map<String, Object>> newLoanTransactions = new ArrayList<Map<String, Object>>();
|
||||
for (final LoanTransaction transaction : this.loanTransactions) {
|
||||
|
||||
+13
-5
@@ -177,7 +177,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
outstandingLoanBalance = command.bigDecimalValueOfParameterNamed(LoanProductConstants.outstandingLoanBalanceParameterName);
|
||||
maxTrancheCount = command.integerValueOfParameterNamed(LoanProductConstants.maxTrancheCountParameterName);
|
||||
}
|
||||
|
||||
|
||||
final Integer graceOnArrearsAgeing = command.integerValueOfParameterNamed(LoanProductConstants.graceOnArrearsAgeingParameterName);
|
||||
|
||||
return new LoanProduct(fund, loanTransactionProcessingStrategy, name, shortName, description, currency, principal, minPrincipal,
|
||||
@@ -186,7 +186,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, amortizationMethod, inArrearsTolerance, productCharges, accountingRuleType, includeInBorrowerCycle,
|
||||
startDate, closeDate, externalId, useBorrowerCycle, loanProductBorrowerCycleVariations, multiDisburseLoan, maxTrancheCount,
|
||||
outstandingLoanBalance,graceOnArrearsAgeing);
|
||||
outstandingLoanBalance, graceOnArrearsAgeing);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -396,7 +396,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
final AccountingRuleType accountingRuleType, final boolean includeInBorrowerCycle, final LocalDate startDate,
|
||||
final LocalDate closeDate, final String externalId, final boolean useBorrowerCycle,
|
||||
final Set<LoanProductBorrowerCycleVariations> loanProductBorrowerCycleVariations, final boolean multiDisburseLoan,
|
||||
final Integer maxTrancheCount, final BigDecimal outstandingLoanBalance,final Integer graceOnArrearsAgeing) {
|
||||
final Integer maxTrancheCount, final BigDecimal outstandingLoanBalance, final Integer graceOnArrearsAgeing) {
|
||||
this.fund = fund;
|
||||
this.transactionProcessingStrategy = transactionProcessingStrategy;
|
||||
this.name = name.trim();
|
||||
@@ -414,7 +414,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod,
|
||||
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery,
|
||||
repaymentFrequencyType, defaultNumberOfInstallments, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, amortizationMethod, inArrearsTolerance,graceOnArrearsAgeing);
|
||||
graceOnInterestCharged, amortizationMethod, inArrearsTolerance, graceOnArrearsAgeing);
|
||||
|
||||
this.loanProductRelatedDetail.validateRepaymentPeriodWithGraceSettings();
|
||||
|
||||
@@ -614,7 +614,15 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public boolean isAccrualBasedAccountingEnabled() {
|
||||
return AccountingRuleType.ACCRUAL_BASED.getValue().equals(this.accountingRule);
|
||||
return isUpfrontAccrualAccounting() || isPeriodicAccrualAccounting();
|
||||
}
|
||||
|
||||
public boolean isUpfrontAccrualAccounting() {
|
||||
return AccountingRuleType.ACCRUAL_UPFRONT.getValue().equals(this.accountingRule);
|
||||
}
|
||||
|
||||
public boolean isPeriodicAccrualAccounting() {
|
||||
return AccountingRuleType.ACCRUAL_PERIODIC.getValue().equals(this.accountingRule);
|
||||
}
|
||||
|
||||
public Money getPrincipalAmount() {
|
||||
|
||||
+11
-2
@@ -254,7 +254,8 @@ public final class LoanProductDataValidator {
|
||||
|
||||
final Integer graceOnArrearsAgeing = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(
|
||||
LoanProductConstants.graceOnArrearsAgeingParameterName, element);
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.graceOnArrearsAgeingParameterName).value(graceOnArrearsAgeing).zeroOrPositiveAmount();
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.graceOnArrearsAgeingParameterName).value(graceOnArrearsAgeing)
|
||||
.zeroOrPositiveAmount();
|
||||
|
||||
// accounting related data validation
|
||||
final Integer accountingRuleType = this.fromApiJsonHelper.extractIntegerNamed("accountingRule", element, Locale.getDefault());
|
||||
@@ -973,7 +974,15 @@ public final class LoanProductDataValidator {
|
||||
}
|
||||
|
||||
private boolean isAccrualBasedAccounting(final Integer accountingRuleType) {
|
||||
return AccountingRuleType.ACCRUAL_BASED.getValue().equals(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) {
|
||||
|
||||
+11
-1
@@ -538,8 +538,18 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
return AccountingRuleType.CASH_BASED.getValue().equals(this.accountingRule);
|
||||
}
|
||||
|
||||
// TODO this entire block is currently unnecessary as Savings does not have
|
||||
// accrual accounting
|
||||
public boolean isAccrualBasedAccountingEnabled() {
|
||||
return AccountingRuleType.ACCRUAL_BASED.getValue().equals(this.accountingRule);
|
||||
return isUpfrontAccrualAccounting() || isPeriodicAccrualAccounting();
|
||||
}
|
||||
|
||||
public boolean isPeriodicAccrualAccounting() {
|
||||
return AccountingRuleType.ACCRUAL_PERIODIC.getValue().equals(this.accountingRule);
|
||||
}
|
||||
|
||||
public boolean isUpfrontAccrualAccounting() {
|
||||
return AccountingRuleType.ACCRUAL_UPFRONT.getValue().equals(this.accountingRule);
|
||||
}
|
||||
|
||||
public Integer getAccountingType() {
|
||||
|
||||
Reference in New Issue
Block a user