FINERACT-1806: Rework Product to GL account mapping and fix charge-off reason typos
This commit is contained in:
+2
-2
@@ -69,9 +69,9 @@ public class ProductToGLAccountMapping extends AbstractPersistableCustom<Long> {
|
|||||||
private CodeValue chargeOffReason;
|
private CodeValue chargeOffReason;
|
||||||
|
|
||||||
public static ProductToGLAccountMapping createNew(final GLAccount glAccount, final Long productId, final int productType,
|
public static ProductToGLAccountMapping createNew(final GLAccount glAccount, final Long productId, final int productType,
|
||||||
final int financialAccountType, final CodeValue chargeOffReasonId) {
|
final int financialAccountType, final CodeValue chargeOffReason) {
|
||||||
|
|
||||||
return new ProductToGLAccountMapping().setGlAccount(glAccount).setProductId(productId).setProductType(productType)
|
return new ProductToGLAccountMapping().setGlAccount(glAccount).setProductId(productId).setProductType(productType)
|
||||||
.setFinancialAccountType(financialAccountType).setChargeOffReason(chargeOffReasonId);
|
.setFinancialAccountType(financialAccountType).setChargeOffReason(chargeOffReason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-8
@@ -63,19 +63,22 @@ public interface ProductToGLAccountMappingRepository
|
|||||||
List<ProductToGLAccountMapping> findByProductIdAndProductType(Long productId, int productType);
|
List<ProductToGLAccountMapping> findByProductIdAndProductType(Long productId, int productType);
|
||||||
|
|
||||||
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.chargeOffReason is not NULL")
|
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.chargeOffReason is not NULL")
|
||||||
List<ProductToGLAccountMapping> findAllChargesOffReasonsMappings(@Param("productId") Long productId,
|
List<ProductToGLAccountMapping> findAllChargeOffReasonsMappings(@Param("productId") Long productId,
|
||||||
@Param("productType") int productType);
|
@Param("productType") int productType);
|
||||||
|
|
||||||
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.chargeOffReason.id =:chargeOffReasonId")
|
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.chargeOffReason.id =:chargeOffReasonId")
|
||||||
ProductToGLAccountMapping findChargesOffReasonMappingById(@Param("chargeOffReasonId") Integer chargeOffReasonId);
|
ProductToGLAccountMapping findChargeOffReasonMappingById(@Param("chargeOffReasonId") Integer chargeOffReasonId);
|
||||||
|
|
||||||
List<ProductToGLAccountMapping> findAllByProductIdAndProductTypeAndPaymentTypeIsNullAndChargeIsNull(Long productId,
|
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId AND mapping.productType =:productType AND mapping.charge IS NULL AND mapping.paymentType IS NULL AND mapping.chargeOffReason IS NULL")
|
||||||
Integer productType);
|
List<ProductToGLAccountMapping> findAllRegularMappings(@Param("productId") Long productId, @Param("productType") Integer productType);
|
||||||
|
|
||||||
List<ProductToGLAccountMapping> findAllByProductIdAndProductTypeAndChargeOffReasonIdIsNotNull(Long productId, Integer productType);
|
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.paymentType is not NULL")
|
||||||
|
List<ProductToGLAccountMapping> findAllPaymentTypeMappings(@Param("productId") Long productId,
|
||||||
|
@Param("productType") Integer productType);
|
||||||
|
|
||||||
List<ProductToGLAccountMapping> findAllByProductIdAndProductTypeAndPaymentTypeIsNotNull(Long productId, Integer productType);
|
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId AND mapping.productType =:productType AND mapping.charge.penalty = TRUE")
|
||||||
|
List<ProductToGLAccountMapping> findAllPenaltyMappings(@Param("productId") Long productId, @Param("productType") Integer productType);
|
||||||
|
|
||||||
List<ProductToGLAccountMapping> findAllByProductIdAndProductTypeAndCharge_PenaltyAndCharge_IdIsNotNull(Long productId,
|
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId AND mapping.productType =:productType AND mapping.charge.penalty = FALSE")
|
||||||
Integer productType, boolean isPenalty);
|
List<ProductToGLAccountMapping> findAllFeeMappings(@Param("productId") Long productId, @Param("productType") Integer productType);
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -204,7 +204,7 @@ public class ProductToGLAccountMappingHelper {
|
|||||||
public void saveChargeOffReasonToGLAccountMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
public void saveChargeOffReasonToGLAccountMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||||
final Map<String, Object> changes, final PortfolioProductType portfolioProductType) {
|
final Map<String, Object> changes, final PortfolioProductType portfolioProductType) {
|
||||||
|
|
||||||
final String arrayName = LoanProductAccountingParams.CHARGE_OFF_REASONS_TO_EXPENSE.getValue();
|
final String arrayName = LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue();
|
||||||
final JsonArray chargeOffReasonToExpenseAccountMappingArray = this.fromApiJsonHelper.extractJsonArrayNamed(arrayName, element);
|
final JsonArray chargeOffReasonToExpenseAccountMappingArray = this.fromApiJsonHelper.extractJsonArrayNamed(arrayName, element);
|
||||||
|
|
||||||
if (chargeOffReasonToExpenseAccountMappingArray != null) {
|
if (chargeOffReasonToExpenseAccountMappingArray != null) {
|
||||||
@@ -388,17 +388,17 @@ public class ProductToGLAccountMappingHelper {
|
|||||||
final Map<String, Object> changes, final PortfolioProductType portfolioProductType) {
|
final Map<String, Object> changes, final PortfolioProductType portfolioProductType) {
|
||||||
|
|
||||||
final List<ProductToGLAccountMapping> existingChargeOffReasonToGLAccountMappings = this.accountMappingRepository
|
final List<ProductToGLAccountMapping> existingChargeOffReasonToGLAccountMappings = this.accountMappingRepository
|
||||||
.findAllChargesOffReasonsMappings(productId, portfolioProductType.getValue());
|
.findAllChargeOffReasonsMappings(productId, portfolioProductType.getValue());
|
||||||
final JsonArray chargeOffReasonToGLAccountMappingArray = this.fromApiJsonHelper
|
final JsonArray chargeOffReasonToGLAccountMappingArray = this.fromApiJsonHelper
|
||||||
.extractJsonArrayNamed(LoanProductAccountingParams.CHARGE_OFF_REASONS_TO_EXPENSE.getValue(), element);
|
.extractJsonArrayNamed(LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue(), element);
|
||||||
|
|
||||||
final Map<Long, Long> inputChargeOffReasonToGLAccountMap = new HashMap<>();
|
final Map<Long, Long> inputChargeOffReasonToGLAccountMap = new HashMap<>();
|
||||||
|
|
||||||
final Set<Long> existingChargeOffReasons = new HashSet<>();
|
final Set<Long> existingChargeOffReasons = new HashSet<>();
|
||||||
if (chargeOffReasonToGLAccountMappingArray != null) {
|
if (chargeOffReasonToGLAccountMappingArray != null) {
|
||||||
if (changes != null) {
|
if (changes != null) {
|
||||||
changes.put(LoanProductAccountingParams.CHARGE_OFF_REASONS_TO_EXPENSE.getValue(),
|
changes.put(LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue(),
|
||||||
command.jsonFragment(LoanProductAccountingParams.CHARGE_OFF_REASONS_TO_EXPENSE.getValue()));
|
command.jsonFragment(LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < chargeOffReasonToGLAccountMappingArray.size(); i++) {
|
for (int i = 0; i < chargeOffReasonToGLAccountMappingArray.size(); i++) {
|
||||||
@@ -495,7 +495,7 @@ public class ProductToGLAccountMappingHelper {
|
|||||||
final Optional<GLAccount> glAccount = accountRepository.findById(expenseAccountId);
|
final Optional<GLAccount> glAccount = accountRepository.findById(expenseAccountId);
|
||||||
|
|
||||||
final boolean reasonMappingExists = this.accountMappingRepository
|
final boolean reasonMappingExists = this.accountMappingRepository
|
||||||
.findAllChargesOffReasonsMappings(productId, portfolioProductType.getValue()).stream()
|
.findAllChargeOffReasonsMappings(productId, portfolioProductType.getValue()).stream()
|
||||||
.anyMatch(mapping -> mapping.getChargeOffReason().getId().equals(reasonId));
|
.anyMatch(mapping -> mapping.getChargeOffReason().getId().equals(reasonId));
|
||||||
|
|
||||||
final Optional<CodeValue> codeValueOptional = codeValueRepository.findById(reasonId);
|
final Optional<CodeValue> codeValueOptional = codeValueRepository.findById(reasonId);
|
||||||
@@ -577,7 +577,7 @@ public class ProductToGLAccountMappingHelper {
|
|||||||
if (codeValue == null) {
|
if (codeValue == null) {
|
||||||
validationErrors.add(ApiParameterError.parameterError("validation.msg.chargeoffreason.invalid",
|
validationErrors.add(ApiParameterError.parameterError("validation.msg.chargeoffreason.invalid",
|
||||||
"Charge-off reason with ID " + chargeOffReasonCodeValueId + " does not exist",
|
"Charge-off reason with ID " + chargeOffReasonCodeValueId + " does not exist",
|
||||||
LoanProductAccountingParams.CHARGE_OFF_REASONS_TO_EXPENSE.getValue()));
|
LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validation: expenseGLAccountId must exist as a valid Expense GL account
|
// Validation: expenseGLAccountId must exist as a valid Expense GL account
|
||||||
|
|||||||
+18
-27
@@ -61,8 +61,8 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
|
|
||||||
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
||||||
|
|
||||||
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository
|
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository.findAllRegularMappings(loanProductId,
|
||||||
.findAllByProductIdAndProductTypeAndPaymentTypeIsNullAndChargeIsNull(loanProductId, PortfolioProductType.LOAN.getValue());
|
PortfolioProductType.LOAN.getValue());
|
||||||
|
|
||||||
if (AccountingValidations.isCashBasedAccounting(accountingType)) {
|
if (AccountingValidations.isCashBasedAccounting(accountingType)) {
|
||||||
|
|
||||||
@@ -178,9 +178,8 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
@Override
|
@Override
|
||||||
public Map<String, Object> fetchAccountMappingDetailsForSavingsProduct(final Long savingsProductId, final Integer accountingType) {
|
public Map<String, Object> fetchAccountMappingDetailsForSavingsProduct(final Long savingsProductId, final Integer accountingType) {
|
||||||
|
|
||||||
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository
|
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository.findAllRegularMappings(savingsProductId,
|
||||||
.findAllByProductIdAndProductTypeAndPaymentTypeIsNullAndChargeIsNull(savingsProductId,
|
PortfolioProductType.SAVING.getValue());
|
||||||
PortfolioProductType.SAVING.getValue());
|
|
||||||
|
|
||||||
Map<String, Object> accountMappingDetails = null;
|
Map<String, Object> accountMappingDetails = null;
|
||||||
if (AccountingValidations.isCashBasedAccounting(accountingType)) {
|
if (AccountingValidations.isCashBasedAccounting(accountingType)) {
|
||||||
@@ -210,14 +209,11 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
*/
|
*/
|
||||||
private List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappings(final PortfolioProductType portfolioProductType,
|
private List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappings(final PortfolioProductType portfolioProductType,
|
||||||
final Long loanProductId) {
|
final Long loanProductId) {
|
||||||
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository
|
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository.findAllPaymentTypeMappings(loanProductId,
|
||||||
.findAllByProductIdAndProductTypeAndPaymentTypeIsNotNull(loanProductId, portfolioProductType.getValue());
|
portfolioProductType.getValue());
|
||||||
|
|
||||||
List<PaymentTypeToGLAccountMapper> paymentTypeToGLAccountMappers = null;
|
List<PaymentTypeToGLAccountMapper> paymentTypeToGLAccountMappers = mappings.isEmpty() ? null : new ArrayList<>();
|
||||||
for (final ProductToGLAccountMapping mapping : mappings) {
|
for (final ProductToGLAccountMapping mapping : mappings) {
|
||||||
if (paymentTypeToGLAccountMappers == null) {
|
|
||||||
paymentTypeToGLAccountMappers = new ArrayList<>();
|
|
||||||
}
|
|
||||||
final PaymentTypeData paymentTypeData = PaymentTypeData.instance(mapping.getPaymentType().getId(),
|
final PaymentTypeData paymentTypeData = PaymentTypeData.instance(mapping.getPaymentType().getId(),
|
||||||
mapping.getPaymentType().getName());
|
mapping.getPaymentType().getName());
|
||||||
final GLAccountData gLAccountData = new GLAccountData().setId(mapping.getGlAccount().getId())
|
final GLAccountData gLAccountData = new GLAccountData().setId(mapping.getGlAccount().getId())
|
||||||
@@ -252,14 +248,12 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
|
|
||||||
private List<ChargeToGLAccountMapper> fetchChargeToIncomeAccountMappings(final PortfolioProductType portfolioProductType,
|
private List<ChargeToGLAccountMapper> fetchChargeToIncomeAccountMappings(final PortfolioProductType portfolioProductType,
|
||||||
final Long loanProductId, final boolean penalty) {
|
final Long loanProductId, final boolean penalty) {
|
||||||
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository
|
final List<ProductToGLAccountMapping> mappings = penalty
|
||||||
.findAllByProductIdAndProductTypeAndCharge_PenaltyAndCharge_IdIsNotNull(loanProductId, portfolioProductType.getValue(),
|
? productToGLAccountMappingRepository.findAllPenaltyMappings(loanProductId, portfolioProductType.getValue())
|
||||||
penalty);
|
: productToGLAccountMappingRepository.findAllFeeMappings(loanProductId, portfolioProductType.getValue());
|
||||||
List<ChargeToGLAccountMapper> chargeToGLAccountMappers = null;
|
|
||||||
|
List<ChargeToGLAccountMapper> chargeToGLAccountMappers = mappings.isEmpty() ? null : new ArrayList<>();
|
||||||
for (final ProductToGLAccountMapping mapping : mappings) {
|
for (final ProductToGLAccountMapping mapping : mappings) {
|
||||||
if (chargeToGLAccountMappers == null) {
|
|
||||||
chargeToGLAccountMappers = new ArrayList<>();
|
|
||||||
}
|
|
||||||
final GLAccountData gLAccountData = new GLAccountData().setId(mapping.getGlAccount().getId())
|
final GLAccountData gLAccountData = new GLAccountData().setId(mapping.getGlAccount().getId())
|
||||||
.setName(mapping.getGlAccount().getName()).setGlCode(mapping.getGlAccount().getGlCode());
|
.setName(mapping.getGlAccount().getName()).setGlCode(mapping.getGlAccount().getGlCode());
|
||||||
final ChargeData chargeData = ChargeData.builder().id(mapping.getCharge().getId()).name(mapping.getCharge().getName())
|
final ChargeData chargeData = ChargeData.builder().id(mapping.getCharge().getId()).name(mapping.getCharge().getName())
|
||||||
@@ -273,13 +267,10 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
|
|
||||||
private List<ChargeOffReasonToGLAccountMapper> fetchChargeOffReasonMappings(final PortfolioProductType portfolioProductType,
|
private List<ChargeOffReasonToGLAccountMapper> fetchChargeOffReasonMappings(final PortfolioProductType portfolioProductType,
|
||||||
final Long loanProductId) {
|
final Long loanProductId) {
|
||||||
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository
|
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository.findAllChargeOffReasonsMappings(loanProductId,
|
||||||
.findAllByProductIdAndProductTypeAndChargeOffReasonIdIsNotNull(loanProductId, portfolioProductType.getValue());
|
portfolioProductType.getValue());
|
||||||
List<ChargeOffReasonToGLAccountMapper> chargeOffReasonToGLAccountMappers = null;
|
List<ChargeOffReasonToGLAccountMapper> chargeOffReasonToGLAccountMappers = mappings.isEmpty() ? null : new ArrayList<>();
|
||||||
for (final ProductToGLAccountMapping mapping : mappings) {
|
for (final ProductToGLAccountMapping mapping : mappings) {
|
||||||
if (chargeOffReasonToGLAccountMappers == null) {
|
|
||||||
chargeOffReasonToGLAccountMappers = new ArrayList<>();
|
|
||||||
}
|
|
||||||
final Long glAccountId = mapping.getGlAccount().getId();
|
final Long glAccountId = mapping.getGlAccount().getId();
|
||||||
final String glAccountName = mapping.getGlAccount().getName();
|
final String glAccountName = mapping.getGlAccount().getName();
|
||||||
final String glCode = mapping.getGlAccount().getGlCode();
|
final String glCode = mapping.getGlAccount().getGlCode();
|
||||||
@@ -294,7 +285,7 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
.description(codeDescription).position(orderPosition).active(isActive).mandatory(isMandatory).build();
|
.description(codeDescription).position(orderPosition).active(isActive).mandatory(isMandatory).build();
|
||||||
|
|
||||||
final ChargeOffReasonToGLAccountMapper chargeOffReasonToGLAccountMapper = new ChargeOffReasonToGLAccountMapper()
|
final ChargeOffReasonToGLAccountMapper chargeOffReasonToGLAccountMapper = new ChargeOffReasonToGLAccountMapper()
|
||||||
.setChargeOffReasonsCodeValue(chargeOffReasonsCodeValue).setChargeOffExpenseAccount(chargeOffExpenseAccount);
|
.setChargeOffReasonCodeValue(chargeOffReasonsCodeValue).setChargeOffExpenseAccount(chargeOffExpenseAccount);
|
||||||
chargeOffReasonToGLAccountMappers.add(chargeOffReasonToGLAccountMapper);
|
chargeOffReasonToGLAccountMappers.add(chargeOffReasonToGLAccountMapper);
|
||||||
}
|
}
|
||||||
return chargeOffReasonToGLAccountMappers;
|
return chargeOffReasonToGLAccountMappers;
|
||||||
@@ -305,8 +296,8 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
|
|
||||||
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
||||||
|
|
||||||
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository
|
final List<ProductToGLAccountMapping> mappings = productToGLAccountMappingRepository.findAllRegularMappings(productId,
|
||||||
.findAllByProductIdAndProductTypeAndPaymentTypeIsNullAndChargeIsNull(productId, PortfolioProductType.SHARES.getValue());
|
PortfolioProductType.SHARES.getValue());
|
||||||
|
|
||||||
if (AccountingRuleType.CASH_BASED.getValue().equals(accountingType)) {
|
if (AccountingRuleType.CASH_BASED.getValue().equals(accountingType)) {
|
||||||
for (final ProductToGLAccountMapping mapping : mappings) {
|
for (final ProductToGLAccountMapping mapping : mappings) {
|
||||||
|
|||||||
+1
-1
@@ -173,7 +173,7 @@ public final class AccountingConstants {
|
|||||||
INCOME_FROM_GOODWILL_CREDIT_INTEREST("incomeFromGoodwillCreditInterestAccountId"), //
|
INCOME_FROM_GOODWILL_CREDIT_INTEREST("incomeFromGoodwillCreditInterestAccountId"), //
|
||||||
INCOME_FROM_GOODWILL_CREDIT_FEES("incomeFromGoodwillCreditFeesAccountId"), //
|
INCOME_FROM_GOODWILL_CREDIT_FEES("incomeFromGoodwillCreditFeesAccountId"), //
|
||||||
INCOME_FROM_GOODWILL_CREDIT_PENALTY("incomeFromGoodwillCreditPenaltyAccountId"), //
|
INCOME_FROM_GOODWILL_CREDIT_PENALTY("incomeFromGoodwillCreditPenaltyAccountId"), //
|
||||||
CHARGE_OFF_REASONS_TO_EXPENSE("chargeOffReasonsToExpenseMappings"), //
|
CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS("chargeOffReasonToExpenseAccountMappings"), //
|
||||||
EXPENSE_GL_ACCOUNT_ID("expenseGLAccountId"), //
|
EXPENSE_GL_ACCOUNT_ID("expenseGLAccountId"), //
|
||||||
CHARGE_OFF_REASON_CODE_VALUE_ID("chargeOffReasonCodeValueId"); //
|
CHARGE_OFF_REASON_CODE_VALUE_ID("chargeOffReasonCodeValueId"); //
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -31,6 +31,6 @@ import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
|||||||
public class ChargeOffReasonToGLAccountMapper implements Serializable {
|
public class ChargeOffReasonToGLAccountMapper implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private CodeValueData chargeOffReasonsCodeValue;
|
private CodeValueData chargeOffReasonCodeValue;
|
||||||
private GLAccountData chargeOffExpenseAccount;
|
private GLAccountData chargeOffExpenseAccount;
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -248,7 +248,7 @@ final class LoanProductsApiResourceSwagger {
|
|||||||
public Long incomeFromGoodwillCreditPenaltyAccountId;
|
public Long incomeFromGoodwillCreditPenaltyAccountId;
|
||||||
public List<GetLoanProductsProductIdResponse.GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings;
|
public List<GetLoanProductsProductIdResponse.GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings;
|
||||||
public List<GetLoanProductsProductIdResponse.GetLoanFeeToIncomeAccountMappings> feeToIncomeAccountMappings;
|
public List<GetLoanProductsProductIdResponse.GetLoanFeeToIncomeAccountMappings> feeToIncomeAccountMappings;
|
||||||
public List<PostChargeOffReasonsToExpenseMappings> chargeOffReasonsToExpenseMappings;
|
public List<PostChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings;
|
||||||
public List<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings;
|
public List<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings;
|
||||||
|
|
||||||
// Multi Disburse
|
// Multi Disburse
|
||||||
@@ -326,9 +326,9 @@ final class LoanProductsApiResourceSwagger {
|
|||||||
@Schema(example = "REGULAR")
|
@Schema(example = "REGULAR")
|
||||||
public String chargeOffBehaviour;
|
public String chargeOffBehaviour;
|
||||||
|
|
||||||
static final class PostChargeOffReasonsToExpenseMappings {
|
static final class PostChargeOffReasonToExpenseAccountMappings {
|
||||||
|
|
||||||
private PostChargeOffReasonsToExpenseMappings() {}
|
private PostChargeOffReasonToExpenseAccountMappings() {}
|
||||||
|
|
||||||
@Schema(example = "1")
|
@Schema(example = "1")
|
||||||
public Long chargeOffReasonCodeValueId;
|
public Long chargeOffReasonCodeValueId;
|
||||||
@@ -1229,9 +1229,9 @@ final class LoanProductsApiResourceSwagger {
|
|||||||
public Long fundSourceAccountId;
|
public Long fundSourceAccountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class GetChargeOffReasonsToExpenseMappings {
|
static final class GetChargeOffReasonToExpenseAccountMappings {
|
||||||
|
|
||||||
private GetChargeOffReasonsToExpenseMappings() {}
|
private GetChargeOffReasonToExpenseAccountMappings() {}
|
||||||
|
|
||||||
public GetCodeValueData chargeOffReasonCodeValue;
|
public GetCodeValueData chargeOffReasonCodeValue;
|
||||||
public GetGLAccountData chargeOffExpenseAccount;
|
public GetGLAccountData chargeOffExpenseAccount;
|
||||||
@@ -1376,7 +1376,7 @@ final class LoanProductsApiResourceSwagger {
|
|||||||
public GetLoanAccountingMappings accountingMappings;
|
public GetLoanAccountingMappings accountingMappings;
|
||||||
public Set<GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings;
|
public Set<GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings;
|
||||||
public Set<GetLoanFeeToIncomeAccountMappings> feeToIncomeAccountMappings;
|
public Set<GetLoanFeeToIncomeAccountMappings> feeToIncomeAccountMappings;
|
||||||
public Set<GetChargeOffReasonsToExpenseMappings> chargeOffReasonToGLAccountMappings;
|
public List<GetChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings;
|
||||||
@Schema(example = "false")
|
@Schema(example = "false")
|
||||||
public Boolean isRatesEnabled;
|
public Boolean isRatesEnabled;
|
||||||
@Schema(example = "true")
|
@Schema(example = "true")
|
||||||
@@ -1636,7 +1636,7 @@ final class LoanProductsApiResourceSwagger {
|
|||||||
public Long incomeFromChargeOffPenaltyAccountId;
|
public Long incomeFromChargeOffPenaltyAccountId;
|
||||||
public List<GetLoanProductsProductIdResponse.GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings;
|
public List<GetLoanProductsProductIdResponse.GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings;
|
||||||
public List<GetLoanProductsProductIdResponse.GetLoanFeeToIncomeAccountMappings> feeToIncomeAccountMappings;
|
public List<GetLoanProductsProductIdResponse.GetLoanFeeToIncomeAccountMappings> feeToIncomeAccountMappings;
|
||||||
public List<PostLoanProductsRequest.PostChargeOffReasonsToExpenseMappings> chargeOffReasonsToExpenseMappings;
|
public List<PostLoanProductsRequest.PostChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings;
|
||||||
public List<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings;
|
public List<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings;
|
||||||
@Schema(example = "false")
|
@Schema(example = "false")
|
||||||
public Boolean enableAccrualActivityPosting;
|
public Boolean enableAccrualActivityPosting;
|
||||||
|
|||||||
+4
-4
@@ -154,7 +154,7 @@ public class LoanProductData implements Serializable {
|
|||||||
private Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings;
|
private Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings;
|
||||||
private Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings;
|
private Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings;
|
||||||
private Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings;
|
private Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings;
|
||||||
private List<ChargeOffReasonToGLAccountMapper> chargeOffReasonToGLAccountMappings;
|
private List<ChargeOffReasonToGLAccountMapper> chargeOffReasonToExpenseAccountMappings;
|
||||||
private final boolean enableAccrualActivityPosting;
|
private final boolean enableAccrualActivityPosting;
|
||||||
|
|
||||||
// rates
|
// rates
|
||||||
@@ -747,7 +747,7 @@ public class LoanProductData implements Serializable {
|
|||||||
productData.paymentChannelToFundSourceMappings = paymentChannelToFundSourceMappings;
|
productData.paymentChannelToFundSourceMappings = paymentChannelToFundSourceMappings;
|
||||||
productData.feeToIncomeAccountMappings = feeToGLAccountMappings;
|
productData.feeToIncomeAccountMappings = feeToGLAccountMappings;
|
||||||
productData.penaltyToIncomeAccountMappings = penaltyToGLAccountMappings;
|
productData.penaltyToIncomeAccountMappings = penaltyToGLAccountMappings;
|
||||||
productData.chargeOffReasonToGLAccountMappings = chargeOffReasonToGLAccountMappings;
|
productData.chargeOffReasonToExpenseAccountMappings = chargeOffReasonToGLAccountMappings;
|
||||||
return productData;
|
return productData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -865,7 +865,7 @@ public class LoanProductData implements Serializable {
|
|||||||
this.paymentChannelToFundSourceMappings = null;
|
this.paymentChannelToFundSourceMappings = null;
|
||||||
this.feeToIncomeAccountMappings = null;
|
this.feeToIncomeAccountMappings = null;
|
||||||
this.penaltyToIncomeAccountMappings = null;
|
this.penaltyToIncomeAccountMappings = null;
|
||||||
this.chargeOffReasonToGLAccountMappings = null;
|
this.chargeOffReasonToExpenseAccountMappings = null;
|
||||||
this.valueConditionTypeOptions = null;
|
this.valueConditionTypeOptions = null;
|
||||||
this.principalVariationsForBorrowerCycle = principalVariations;
|
this.principalVariationsForBorrowerCycle = principalVariations;
|
||||||
this.interestRateVariationsForBorrowerCycle = interestRateVariations;
|
this.interestRateVariationsForBorrowerCycle = interestRateVariations;
|
||||||
@@ -1008,7 +1008,7 @@ public class LoanProductData implements Serializable {
|
|||||||
this.paymentChannelToFundSourceMappings = productData.paymentChannelToFundSourceMappings;
|
this.paymentChannelToFundSourceMappings = productData.paymentChannelToFundSourceMappings;
|
||||||
this.feeToIncomeAccountMappings = productData.feeToIncomeAccountMappings;
|
this.feeToIncomeAccountMappings = productData.feeToIncomeAccountMappings;
|
||||||
this.penaltyToIncomeAccountMappings = productData.penaltyToIncomeAccountMappings;
|
this.penaltyToIncomeAccountMappings = productData.penaltyToIncomeAccountMappings;
|
||||||
this.chargeOffReasonToGLAccountMappings = productData.chargeOffReasonToGLAccountMappings;
|
this.chargeOffReasonToExpenseAccountMappings = productData.chargeOffReasonToExpenseAccountMappings;
|
||||||
|
|
||||||
this.chargeOptions = chargeOptions;
|
this.chargeOptions = chargeOptions;
|
||||||
this.penaltyOptions = penaltyOptions;
|
this.penaltyOptions = penaltyOptions;
|
||||||
|
|||||||
+1
-1
@@ -178,7 +178,7 @@ public class AccountingProcessorHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ProductToGLAccountMapping getChargeOffMappingByCodeValue(Integer chargeOffReasonCodeValue) {
|
public ProductToGLAccountMapping getChargeOffMappingByCodeValue(Integer chargeOffReasonCodeValue) {
|
||||||
return accountMappingRepository.findChargesOffReasonMappingById(chargeOffReasonCodeValue);
|
return accountMappingRepository.findChargeOffReasonMappingById(chargeOffReasonCodeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SavingsDTO populateSavingsDtoFromMap(final Map<String, Object> accountingBridgeData, final boolean cashBasedAccountingEnabled,
|
public SavingsDTO populateSavingsDtoFromMap(final Map<String, Object> accountingBridgeData, final boolean cashBasedAccountingEnabled,
|
||||||
|
|||||||
+3
-1
@@ -232,7 +232,9 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
|||||||
// need to fetch if there are account mappings (always one)
|
// need to fetch if there are account mappings (always one)
|
||||||
Integer chargeOffReasonCodeValue = loanDTO.getChargeOffReasonCodeValue();
|
Integer chargeOffReasonCodeValue = loanDTO.getChargeOffReasonCodeValue();
|
||||||
|
|
||||||
ProductToGLAccountMapping mapping = helper.getChargeOffMappingByCodeValue(chargeOffReasonCodeValue);
|
ProductToGLAccountMapping mapping = chargeOffReasonCodeValue != null
|
||||||
|
? helper.getChargeOffMappingByCodeValue(chargeOffReasonCodeValue)
|
||||||
|
: null;
|
||||||
if (mapping != null) {
|
if (mapping != null) {
|
||||||
GLAccount accountCredit = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
GLAccount accountCredit = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||||
AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), paymentTypeId);
|
AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), paymentTypeId);
|
||||||
|
|||||||
+54
-65
@@ -30,6 +30,7 @@ import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsFor
|
|||||||
import org.apache.fineract.accounting.common.AccountingConstants.FinancialActivity;
|
import org.apache.fineract.accounting.common.AccountingConstants.FinancialActivity;
|
||||||
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
||||||
import org.apache.fineract.accounting.journalentry.data.ChargePaymentDTO;
|
import org.apache.fineract.accounting.journalentry.data.ChargePaymentDTO;
|
||||||
|
import org.apache.fineract.accounting.journalentry.data.GLAccountBalanceHolder;
|
||||||
import org.apache.fineract.accounting.journalentry.data.LoanDTO;
|
import org.apache.fineract.accounting.journalentry.data.LoanDTO;
|
||||||
import org.apache.fineract.accounting.journalentry.data.LoanTransactionDTO;
|
import org.apache.fineract.accounting.journalentry.data.LoanTransactionDTO;
|
||||||
import org.apache.fineract.infrastructure.core.service.MathUtil;
|
import org.apache.fineract.infrastructure.core.service.MathUtil;
|
||||||
@@ -139,71 +140,59 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
|
|||||||
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
|
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
|
||||||
final boolean isReversal = loanTransactionDTO.isReversed();
|
final boolean isReversal = loanTransactionDTO.isReversed();
|
||||||
|
|
||||||
Map<GLAccount, BigDecimal> accountMapForCredit = new LinkedHashMap<>();
|
GLAccountBalanceHolder glAccountBalanceHolder = new GLAccountBalanceHolder();
|
||||||
|
|
||||||
Map<Integer, BigDecimal> accountMapForDebit = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
// principal payment
|
// principal payment
|
||||||
if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
if (isMarkedFraud) {
|
if (isMarkedFraud) {
|
||||||
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId, CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
|
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId, CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
|
||||||
CashAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue(), glAccountBalanceHolder);
|
||||||
} else {
|
} else {
|
||||||
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId, CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
|
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId, CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
|
||||||
CashAccountsForLoan.CHARGE_OFF_EXPENSE.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.CHARGE_OFF_EXPENSE.getValue(), glAccountBalanceHolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// interest payment
|
// interest payment
|
||||||
if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
|
if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId, CashAccountsForLoan.INTEREST_ON_LOANS.getValue(),
|
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId, CashAccountsForLoan.INTEREST_ON_LOANS.getValue(),
|
||||||
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(), glAccountBalanceHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle fees payment
|
// handle fees payment
|
||||||
if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_FEES.getValue(),
|
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_FEES.getValue(),
|
||||||
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_FEES.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_FEES.getValue(), glAccountBalanceHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle penalties payment
|
// handle penalties payment
|
||||||
if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_PENALTIES.getValue(),
|
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_PENALTIES.getValue(),
|
||||||
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_PENALTY.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_PENALTY.getValue(), glAccountBalanceHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create credit entries
|
// create credit entries
|
||||||
for (Map.Entry<GLAccount, BigDecimal> creditEntry : accountMapForCredit.entrySet()) {
|
for (Map.Entry<Long, BigDecimal> creditEntry : glAccountBalanceHolder.getCreditBalances().entrySet()) {
|
||||||
|
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(creditEntry.getKey());
|
||||||
this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
||||||
creditEntry.getValue(), isReversal, creditEntry.getKey());
|
creditEntry.getValue(), isReversal, glAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create debit entries
|
// create debit entries
|
||||||
for (Map.Entry<Integer, BigDecimal> debitEntry : accountMapForDebit.entrySet()) {
|
for (Map.Entry<Long, BigDecimal> debitEntry : glAccountBalanceHolder.getDebitBalances().entrySet()) {
|
||||||
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, debitEntry.getKey().intValue(), loanProductId,
|
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(debitEntry.getKey());
|
||||||
paymentTypeId, loanId, transactionId, transactionDate, debitEntry.getValue(), isReversal);
|
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
||||||
|
debitEntry.getValue(), isReversal, glAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateCreditDebitMaps(Long loanProductId, BigDecimal transactionPartAmount, Long paymentTypeId,
|
private void populateCreditDebitMaps(Long loanProductId, BigDecimal transactionPartAmount, Long paymentTypeId,
|
||||||
Integer creditAccountType, Integer debitAccountType, Map<GLAccount, BigDecimal> accountMapForCredit,
|
Integer creditAccountType, Integer debitAccountType, GLAccountBalanceHolder glAccountBalanceHolder) {
|
||||||
Map<Integer, BigDecimal> accountMapForDebit) {
|
// Resolve Credit
|
||||||
GLAccount accountCredit = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, creditAccountType, paymentTypeId);
|
GLAccount accountCredit = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, creditAccountType, paymentTypeId);
|
||||||
if (accountMapForCredit.containsKey(accountCredit)) {
|
glAccountBalanceHolder.addToCredit(accountCredit, transactionPartAmount);
|
||||||
BigDecimal amount = accountMapForCredit.get(accountCredit).add(transactionPartAmount);
|
// Resolve Debit
|
||||||
accountMapForCredit.put(accountCredit, amount);
|
GLAccount accountDebit = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, debitAccountType, paymentTypeId);
|
||||||
} else {
|
glAccountBalanceHolder.addToDebit(accountDebit, transactionPartAmount);
|
||||||
accountMapForCredit.put(accountCredit, transactionPartAmount);
|
|
||||||
}
|
|
||||||
Integer accountDebit = returnExistingDebitAccountInMapMatchingGLAccount(loanProductId, paymentTypeId, debitAccountType,
|
|
||||||
accountMapForDebit);
|
|
||||||
if (accountMapForDebit.containsKey(accountDebit)) {
|
|
||||||
BigDecimal amount = accountMapForDebit.get(accountDebit).add(transactionPartAmount);
|
|
||||||
accountMapForDebit.put(accountDebit, amount);
|
|
||||||
} else {
|
|
||||||
accountMapForDebit.put(accountDebit, transactionPartAmount);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Integer returnExistingDebitAccountInMapMatchingGLAccount(Long loanProductId, Long paymentTypeId, Integer accountType,
|
private Integer returnExistingDebitAccountInMapMatchingGLAccount(Long loanProductId, Long paymentTypeId, Integer accountType,
|
||||||
@@ -568,9 +557,7 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
|
|||||||
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
|
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
|
||||||
final boolean isReversal = loanTransactionDTO.isReversed();
|
final boolean isReversal = loanTransactionDTO.isReversed();
|
||||||
|
|
||||||
Map<GLAccount, BigDecimal> accountMapForCredit = new LinkedHashMap<>();
|
GLAccountBalanceHolder glAccountBalanceHolder = new GLAccountBalanceHolder();
|
||||||
Map<Integer, BigDecimal> accountMapForDebit = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
BigDecimal totalDebitAmount = new BigDecimal(0);
|
BigDecimal totalDebitAmount = new BigDecimal(0);
|
||||||
|
|
||||||
// principal payment
|
// principal payment
|
||||||
@@ -580,35 +567,35 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
|
|||||||
if (isMarkedFraud) {
|
if (isMarkedFraud) {
|
||||||
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId,
|
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId,
|
||||||
CashAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
CashAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
||||||
accountMapForCredit, accountMapForDebit);
|
glAccountBalanceHolder);
|
||||||
} else {
|
} else {
|
||||||
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId,
|
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId,
|
||||||
CashAccountsForLoan.CHARGE_OFF_EXPENSE.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
CashAccountsForLoan.CHARGE_OFF_EXPENSE.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
||||||
accountMapForCredit, accountMapForDebit);
|
glAccountBalanceHolder);
|
||||||
}
|
}
|
||||||
} else if (loanTransactionDTO.getTransactionType().isPayoutRefund()) {
|
} else if (loanTransactionDTO.getTransactionType().isPayoutRefund()) {
|
||||||
if (isMarkedFraud) {
|
if (isMarkedFraud) {
|
||||||
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId,
|
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId,
|
||||||
CashAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
CashAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
||||||
accountMapForCredit, accountMapForDebit);
|
glAccountBalanceHolder);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId,
|
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId,
|
||||||
CashAccountsForLoan.CHARGE_OFF_EXPENSE.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
CashAccountsForLoan.CHARGE_OFF_EXPENSE.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
||||||
accountMapForCredit, accountMapForDebit);
|
glAccountBalanceHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (loanTransactionDTO.getTransactionType().isGoodwillCredit()) {
|
} else if (loanTransactionDTO.getTransactionType().isGoodwillCredit()) {
|
||||||
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
||||||
CashAccountsForLoan.GOODWILL_CREDIT.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.GOODWILL_CREDIT.getValue(), glAccountBalanceHolder);
|
||||||
|
|
||||||
} else if (loanTransactionDTO.getTransactionType().isRepayment()) {
|
} else if (loanTransactionDTO.getTransactionType().isRepayment()) {
|
||||||
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
||||||
CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.FUND_SOURCE.getValue(), glAccountBalanceHolder);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId, CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
|
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId, CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
|
||||||
CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.FUND_SOURCE.getValue(), glAccountBalanceHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -619,23 +606,23 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
|
|||||||
if (loanTransactionDTO.getTransactionType().isMerchantIssuedRefund()) {
|
if (loanTransactionDTO.getTransactionType().isMerchantIssuedRefund()) {
|
||||||
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId,
|
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId,
|
||||||
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
||||||
accountMapForCredit, accountMapForDebit);
|
glAccountBalanceHolder);
|
||||||
|
|
||||||
} else if (loanTransactionDTO.getTransactionType().isPayoutRefund()) {
|
} else if (loanTransactionDTO.getTransactionType().isPayoutRefund()) {
|
||||||
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId,
|
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId,
|
||||||
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
||||||
accountMapForCredit, accountMapForDebit);
|
glAccountBalanceHolder);
|
||||||
|
|
||||||
} else if (loanTransactionDTO.getTransactionType().isGoodwillCredit()) {
|
} else if (loanTransactionDTO.getTransactionType().isGoodwillCredit()) {
|
||||||
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
||||||
CashAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_INTEREST.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_INTEREST.getValue(), glAccountBalanceHolder);
|
||||||
} else if (loanTransactionDTO.getTransactionType().isRepayment()) {
|
} else if (loanTransactionDTO.getTransactionType().isRepayment()) {
|
||||||
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
||||||
CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.FUND_SOURCE.getValue(), glAccountBalanceHolder);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId, CashAccountsForLoan.INTEREST_ON_LOANS.getValue(),
|
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId, CashAccountsForLoan.INTEREST_ON_LOANS.getValue(),
|
||||||
CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.FUND_SOURCE.getValue(), glAccountBalanceHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -646,24 +633,24 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
|
|||||||
if (loanTransactionDTO.getTransactionType().isMerchantIssuedRefund()) {
|
if (loanTransactionDTO.getTransactionType().isMerchantIssuedRefund()) {
|
||||||
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId,
|
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId,
|
||||||
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_FEES.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_FEES.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
||||||
accountMapForCredit, accountMapForDebit);
|
glAccountBalanceHolder);
|
||||||
|
|
||||||
} else if (loanTransactionDTO.getTransactionType().isPayoutRefund()) {
|
} else if (loanTransactionDTO.getTransactionType().isPayoutRefund()) {
|
||||||
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId,
|
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId,
|
||||||
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_FEES.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_FEES.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
||||||
accountMapForCredit, accountMapForDebit);
|
glAccountBalanceHolder);
|
||||||
|
|
||||||
} else if (loanTransactionDTO.getTransactionType().isGoodwillCredit()) {
|
} else if (loanTransactionDTO.getTransactionType().isGoodwillCredit()) {
|
||||||
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
||||||
CashAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_FEES.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_FEES.getValue(), glAccountBalanceHolder);
|
||||||
|
|
||||||
} else if (loanTransactionDTO.getTransactionType().isRepayment()) {
|
} else if (loanTransactionDTO.getTransactionType().isRepayment()) {
|
||||||
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
||||||
CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.FUND_SOURCE.getValue(), glAccountBalanceHolder);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_FEES.getValue(),
|
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_FEES.getValue(),
|
||||||
CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.FUND_SOURCE.getValue(), glAccountBalanceHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -674,24 +661,24 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
|
|||||||
if (loanTransactionDTO.getTransactionType().isMerchantIssuedRefund()) {
|
if (loanTransactionDTO.getTransactionType().isMerchantIssuedRefund()) {
|
||||||
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId,
|
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId,
|
||||||
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_PENALTY.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_PENALTY.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
||||||
accountMapForCredit, accountMapForDebit);
|
glAccountBalanceHolder);
|
||||||
|
|
||||||
} else if (loanTransactionDTO.getTransactionType().isPayoutRefund()) {
|
} else if (loanTransactionDTO.getTransactionType().isPayoutRefund()) {
|
||||||
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId,
|
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId,
|
||||||
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_PENALTY.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_PENALTY.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(),
|
||||||
accountMapForCredit, accountMapForDebit);
|
glAccountBalanceHolder);
|
||||||
|
|
||||||
} else if (loanTransactionDTO.getTransactionType().isGoodwillCredit()) {
|
} else if (loanTransactionDTO.getTransactionType().isGoodwillCredit()) {
|
||||||
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
||||||
CashAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(), glAccountBalanceHolder);
|
||||||
|
|
||||||
} else if (loanTransactionDTO.getTransactionType().isRepayment()) {
|
} else if (loanTransactionDTO.getTransactionType().isRepayment()) {
|
||||||
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(),
|
||||||
CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.FUND_SOURCE.getValue(), glAccountBalanceHolder);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_PENALTIES.getValue(),
|
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId, CashAccountsForLoan.INCOME_FROM_PENALTIES.getValue(),
|
||||||
CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.FUND_SOURCE.getValue(), glAccountBalanceHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -701,26 +688,27 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
|
|||||||
totalDebitAmount = totalDebitAmount.add(overPaymentAmount);
|
totalDebitAmount = totalDebitAmount.add(overPaymentAmount);
|
||||||
if (loanTransactionDTO.getTransactionType().isMerchantIssuedRefund()) {
|
if (loanTransactionDTO.getTransactionType().isMerchantIssuedRefund()) {
|
||||||
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
|
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
|
||||||
CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.FUND_SOURCE.getValue(), glAccountBalanceHolder);
|
||||||
|
|
||||||
} else if (loanTransactionDTO.getTransactionType().isPayoutRefund()) {
|
} else if (loanTransactionDTO.getTransactionType().isPayoutRefund()) {
|
||||||
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
|
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
|
||||||
CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.FUND_SOURCE.getValue(), glAccountBalanceHolder);
|
||||||
|
|
||||||
} else if (loanTransactionDTO.getTransactionType().isGoodwillCredit()) {
|
} else if (loanTransactionDTO.getTransactionType().isGoodwillCredit()) {
|
||||||
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
|
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
|
||||||
CashAccountsForLoan.GOODWILL_CREDIT.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.GOODWILL_CREDIT.getValue(), glAccountBalanceHolder);
|
||||||
} else {
|
} else {
|
||||||
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
|
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
|
||||||
CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
|
CashAccountsForLoan.FUND_SOURCE.getValue(), glAccountBalanceHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create credit entries
|
// create credit entries
|
||||||
for (Map.Entry<GLAccount, BigDecimal> creditEntry : accountMapForCredit.entrySet()) {
|
for (Map.Entry<Long, BigDecimal> creditEntry : glAccountBalanceHolder.getCreditBalances().entrySet()) {
|
||||||
|
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(creditEntry.getKey());
|
||||||
this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
||||||
creditEntry.getValue(), isReversal, creditEntry.getKey());
|
creditEntry.getValue(), isReversal, glAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** create a single debit entry (or reversal) for the entire amount **/
|
/*** create a single debit entry (or reversal) for the entire amount **/
|
||||||
@@ -732,9 +720,10 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
|
|||||||
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount, isReversal);
|
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount, isReversal);
|
||||||
} else {
|
} else {
|
||||||
// create debit entries
|
// create debit entries
|
||||||
for (Map.Entry<Integer, BigDecimal> debitEntry : accountMapForDebit.entrySet()) {
|
for (Map.Entry<Long, BigDecimal> debitEntry : glAccountBalanceHolder.getDebitBalances().entrySet()) {
|
||||||
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, debitEntry.getKey().intValue(), loanProductId,
|
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(debitEntry.getKey());
|
||||||
paymentTypeId, loanId, transactionId, transactionDate, debitEntry.getValue(), isReversal);
|
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
||||||
|
debitEntry.getValue(), isReversal, glAccount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -162,7 +162,7 @@ public class LoanProductsApiResource {
|
|||||||
@Operation(summary = "Create a Loan Product", description = "Depending of the Accounting Rule (accountingRule) selected, additional fields with details of the appropriate Ledger Account identifiers would need to be passed in.\n"
|
@Operation(summary = "Create a Loan Product", description = "Depending of the Accounting Rule (accountingRule) selected, additional fields with details of the appropriate Ledger Account identifiers would need to be passed in.\n"
|
||||||
+ "\n" + "Refer MifosX Accounting Specs Draft for more details regarding the significance of the selected accounting rule\n\n"
|
+ "\n" + "Refer MifosX Accounting Specs Draft for more details regarding the significance of the selected accounting rule\n\n"
|
||||||
+ "Mandatory Fields: name, shortName, currencyCode, digitsAfterDecimal, inMultiplesOf, principal, numberOfRepayments, repaymentEvery, repaymentFrequencyType, interestRatePerPeriod, interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, transactionProcessingStrategyCode, accountingRule, isInterestRecalculationEnabled, daysInYearType, daysInMonthType\n\n"
|
+ "Mandatory Fields: name, shortName, currencyCode, digitsAfterDecimal, inMultiplesOf, principal, numberOfRepayments, repaymentEvery, repaymentFrequencyType, interestRatePerPeriod, interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, transactionProcessingStrategyCode, accountingRule, isInterestRecalculationEnabled, daysInYearType, daysInMonthType\n\n"
|
||||||
+ "Optional Fields: inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, graceOnArrearsAgeing, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, chargeOffReasonsToExpenseMappings, includeInBorrowerCycle, useBorrowerCycle,principalVariationsForBorrowerCycle, numberOfRepaymentVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle, multiDisburseLoan,maxTrancheCount, outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, allowAttributeOverrides, allowPartialPeriodInterestCalcualtion,dueDaysForRepaymentEvent,overDueDaysForRepaymentEvent,enableDownPayment,disbursedAmountPercentageDownPayment,enableAutoRepaymentForDownPayment,repaymentStartDateType\n\n"
|
+ "Optional Fields: inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, graceOnArrearsAgeing, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, chargeOffReasonToExpenseAccountMappings, includeInBorrowerCycle, useBorrowerCycle,principalVariationsForBorrowerCycle, numberOfRepaymentVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle, multiDisburseLoan,maxTrancheCount, outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, allowAttributeOverrides, allowPartialPeriodInterestCalcualtion,dueDaysForRepaymentEvent,overDueDaysForRepaymentEvent,enableDownPayment,disbursedAmountPercentageDownPayment,enableAutoRepaymentForDownPayment,repaymentStartDateType\n\n"
|
||||||
+ "Additional Mandatory Fields for Cash(2) based accounting: fundSourceAccountId, loanPortfolioAccountId, interestOnLoanAccountId, incomeFromFeeAccountId, incomeFromPenaltyAccountId, writeOffAccountId, transfersInSuspenseAccountId, overpaymentLiabilityAccountId\n\n"
|
+ "Additional Mandatory Fields for Cash(2) based accounting: fundSourceAccountId, loanPortfolioAccountId, interestOnLoanAccountId, incomeFromFeeAccountId, incomeFromPenaltyAccountId, writeOffAccountId, transfersInSuspenseAccountId, overpaymentLiabilityAccountId\n\n"
|
||||||
+ "Additional Mandatory Fields for periodic (3) and upfront (4)accrual accounting: fundSourceAccountId, loanPortfolioAccountId, interestOnLoanAccountId, incomeFromFeeAccountId, incomeFromPenaltyAccountId, writeOffAccountId, receivableInterestAccountId, receivableFeeAccountId, receivablePenaltyAccountId, transfersInSuspenseAccountId, overpaymentLiabilityAccountId\n\n"
|
+ "Additional Mandatory Fields for periodic (3) and upfront (4)accrual accounting: fundSourceAccountId, loanPortfolioAccountId, interestOnLoanAccountId, incomeFromFeeAccountId, incomeFromPenaltyAccountId, writeOffAccountId, receivableInterestAccountId, receivableFeeAccountId, receivablePenaltyAccountId, transfersInSuspenseAccountId, overpaymentLiabilityAccountId\n\n"
|
||||||
+ "Additional Mandatory Fields if interest recalculation is enabled(true): interestRecalculationCompoundingMethod, rescheduleStrategyMethod, recalculationRestFrequencyType\n\n"
|
+ "Additional Mandatory Fields if interest recalculation is enabled(true): interestRecalculationCompoundingMethod, rescheduleStrategyMethod, recalculationRestFrequencyType\n\n"
|
||||||
|
|||||||
+2
-2
@@ -144,7 +144,7 @@ public final class LoanProductDataValidator {
|
|||||||
LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_INTEREST.getValue(),
|
LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_INTEREST.getValue(),
|
||||||
LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_FEES.getValue(),
|
LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_FEES.getValue(),
|
||||||
LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(),
|
LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(),
|
||||||
LoanProductAccountingParams.CHARGE_OFF_REASONS_TO_EXPENSE.getValue(),
|
LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue(),
|
||||||
LoanProductAccountingParams.EXPENSE_GL_ACCOUNT_ID.getValue(),
|
LoanProductAccountingParams.EXPENSE_GL_ACCOUNT_ID.getValue(),
|
||||||
LoanProductAccountingParams.CHARGE_OFF_REASON_CODE_VALUE_ID.getValue(), LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME,
|
LoanProductAccountingParams.CHARGE_OFF_REASON_CODE_VALUE_ID.getValue(), LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME,
|
||||||
LoanProductConstants.PRINCIPAL_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME,
|
LoanProductConstants.PRINCIPAL_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME,
|
||||||
@@ -1992,7 +1992,7 @@ public final class LoanProductDataValidator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void validateChargeOffToExpenseMappings(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
|
private void validateChargeOffToExpenseMappings(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
|
||||||
String parameterName = LoanProductAccountingParams.CHARGE_OFF_REASONS_TO_EXPENSE.getValue();
|
String parameterName = LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue();
|
||||||
|
|
||||||
if (this.fromApiJsonHelper.parameterExists(parameterName, element)) {
|
if (this.fromApiJsonHelper.parameterExists(parameterName, element)) {
|
||||||
final JsonArray chargeOffToExpenseMappingArray = this.fromApiJsonHelper.extractJsonArrayNamed(parameterName, element);
|
final JsonArray chargeOffToExpenseMappingArray = this.fromApiJsonHelper.extractJsonArrayNamed(parameterName, element);
|
||||||
|
|||||||
+42
-63
@@ -20,11 +20,6 @@ package org.apache.fineract.integrationtests;
|
|||||||
|
|
||||||
import static org.apache.fineract.integrationtests.common.funds.FundsResourceHandler.createFund;
|
import static org.apache.fineract.integrationtests.common.funds.FundsResourceHandler.createFund;
|
||||||
|
|
||||||
import io.restassured.builder.RequestSpecBuilder;
|
|
||||||
import io.restassured.builder.ResponseSpecBuilder;
|
|
||||||
import io.restassured.http.ContentType;
|
|
||||||
import io.restassured.specification.RequestSpecification;
|
|
||||||
import io.restassured.specification.ResponseSpecification;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -34,84 +29,60 @@ import org.apache.fineract.client.models.ChargeToGLAccountMapper;
|
|||||||
import org.apache.fineract.client.models.GetLoanFeeToIncomeAccountMappings;
|
import org.apache.fineract.client.models.GetLoanFeeToIncomeAccountMappings;
|
||||||
import org.apache.fineract.client.models.GetLoanPaymentChannelToFundSourceMappings;
|
import org.apache.fineract.client.models.GetLoanPaymentChannelToFundSourceMappings;
|
||||||
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
|
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
|
||||||
import org.apache.fineract.client.models.PostChargeOffReasonsToExpenseMappings;
|
import org.apache.fineract.client.models.PostChargeOffReasonToExpenseAccountMappings;
|
||||||
import org.apache.fineract.client.models.PostLoanProductsRequest;
|
import org.apache.fineract.client.models.PostLoanProductsRequest;
|
||||||
import org.apache.fineract.client.models.PutLoanProductsProductIdRequest;
|
import org.apache.fineract.client.models.PutLoanProductsProductIdRequest;
|
||||||
import org.apache.fineract.client.util.CallFailedRuntimeException;
|
import org.apache.fineract.client.util.CallFailedRuntimeException;
|
||||||
import org.apache.fineract.integrationtests.common.BusinessStepHelper;
|
|
||||||
import org.apache.fineract.integrationtests.common.Utils;
|
import org.apache.fineract.integrationtests.common.Utils;
|
||||||
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
|
import org.apache.fineract.integrationtests.common.accounting.Account;
|
||||||
import org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
|
import org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
|
||||||
import org.apache.fineract.integrationtests.common.system.CodeHelper;
|
import org.apache.fineract.integrationtests.common.system.CodeHelper;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class LoanProductChargeOffReasonMappingsTest extends BaseLoanIntegrationTest {
|
public class LoanProductChargeOffReasonMappingsTest extends BaseLoanIntegrationTest {
|
||||||
|
|
||||||
private static final String CODE_VALUE_NAME = "ChargeOffReasons";
|
private static final String CODE_VALUE_NAME = "ChargeOffReasons";
|
||||||
|
private final Account expenseAccount = accountHelper.createExpenseAccount();
|
||||||
private static ResponseSpecification responseSpec;
|
private final Account otherExpenseAccount = accountHelper.createExpenseAccount();
|
||||||
private static RequestSpecification requestSpec;
|
|
||||||
private static LoanTransactionHelper loanTransactionHelper;
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void setup() {
|
|
||||||
Utils.initializeRESTAssured();
|
|
||||||
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
|
||||||
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
|
||||||
requestSpec.header("Fineract-Platform-TenantId", "default");
|
|
||||||
responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
|
||||||
loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
|
|
||||||
BusinessStepHelper businessStepHelper = new BusinessStepHelper();
|
|
||||||
// setup COB Business Steps to prevent test failing due other integration test configurations
|
|
||||||
businessStepHelper.updateSteps("LOAN_CLOSE_OF_BUSINESS", "APPLY_CHARGE_TO_OVERDUE_LOANS", "LOAN_DELINQUENCY_CLASSIFICATION",
|
|
||||||
"CHECK_LOAN_REPAYMENT_DUE", "CHECK_LOAN_REPAYMENT_OVERDUE", "UPDATE_LOAN_ARREARS_AGING", "ADD_PERIODIC_ACCRUAL_ENTRIES",
|
|
||||||
"EXTERNAL_ASSET_OWNER_TRANSFER", "ACCRUAL_ACTIVITY_POSTING");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateLoanProductWithValidChargeOffReason() {
|
public void testCreateAndUpdateLoanProductWithValidChargeOffReason() {
|
||||||
final String creationBusinessDay = "15 January 2023";
|
runAt("15 January 2023", () -> {
|
||||||
runAt(creationBusinessDay, () -> {
|
|
||||||
Integer chargeOffReasons = createChargeOffReason();
|
Integer chargeOffReasons = createChargeOffReason();
|
||||||
Long localLoanProductId = loanTransactionHelper.createLoanProduct(loanProductsRequest(Long.valueOf(chargeOffReasons), 16L))
|
Long localLoanProductId = loanTransactionHelper
|
||||||
|
.createLoanProduct(loanProductsRequest(Long.valueOf(chargeOffReasons), expenseAccount.getAccountID().longValue()))
|
||||||
.getResourceId();
|
.getResourceId();
|
||||||
|
|
||||||
Assertions.assertNotNull(localLoanProductId);
|
Assertions.assertNotNull(localLoanProductId);
|
||||||
|
|
||||||
final GetLoanProductsProductIdResponse loanProduct = loanTransactionHelper.getLoanProduct(localLoanProductId.intValue());
|
GetLoanProductsProductIdResponse loanProductDetails = loanTransactionHelper.getLoanProduct(localLoanProductId.intValue());
|
||||||
Assertions.assertNotNull(loanProduct.getChargeOffReasonToGLAccountMappings());
|
Assertions.assertEquals(expenseAccount.getAccountID().longValue(),
|
||||||
Assertions.assertFalse(loanProduct.getChargeOffReasonToGLAccountMappings().isEmpty());
|
loanProductDetails.getChargeOffReasonToExpenseAccountMappings().get(0).getChargeOffExpenseAccount().getId());
|
||||||
});
|
Assertions.assertEquals(Long.valueOf(chargeOffReasons),
|
||||||
}
|
loanProductDetails.getChargeOffReasonToExpenseAccountMappings().get(0).getChargeOffReasonCodeValue().getId());
|
||||||
|
|
||||||
@Test
|
List<PostChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings = createPostChargeOffReasonToExpenseAccountMappings(
|
||||||
public void testUpdateLoanProductWithValidChargeOffReason() {
|
Long.valueOf(chargeOffReasons), otherExpenseAccount.getAccountID().longValue());
|
||||||
final String creationBusinessDay = "15 January 2023";
|
|
||||||
runAt(creationBusinessDay, () -> {
|
|
||||||
Integer chargeOffReasons = createChargeOffReason();
|
|
||||||
List<PostChargeOffReasonsToExpenseMappings> chargeOffReasonsToExpenseMappings = new ArrayList<>();
|
|
||||||
PostChargeOffReasonsToExpenseMappings getChargeOffReasonsToExpenseMappings = new PostChargeOffReasonsToExpenseMappings();
|
|
||||||
getChargeOffReasonsToExpenseMappings.setChargeOffReasonCodeValueId(Long.valueOf(chargeOffReasons));
|
|
||||||
getChargeOffReasonsToExpenseMappings.setExpenseGLAccountId(15L);
|
|
||||||
chargeOffReasonsToExpenseMappings.add(getChargeOffReasonsToExpenseMappings);
|
|
||||||
|
|
||||||
Long localLoanProductId = loanTransactionHelper.updateLoanProduct(1L,
|
loanTransactionHelper.updateLoanProduct(localLoanProductId, new PutLoanProductsProductIdRequest().locale("en")
|
||||||
new PutLoanProductsProductIdRequest().locale("en").chargeOffReasonsToExpenseMappings(chargeOffReasonsToExpenseMappings))
|
.chargeOffReasonToExpenseAccountMappings(chargeOffReasonToExpenseAccountMappings)).getResourceId();
|
||||||
.getResourceId();
|
|
||||||
|
|
||||||
Assertions.assertNotNull(localLoanProductId);
|
loanProductDetails = loanTransactionHelper.getLoanProduct(localLoanProductId.intValue());
|
||||||
|
Assertions.assertEquals(otherExpenseAccount.getAccountID().longValue(),
|
||||||
|
loanProductDetails.getChargeOffReasonToExpenseAccountMappings().get(0).getChargeOffExpenseAccount().getId());
|
||||||
|
Assertions.assertEquals(Long.valueOf(chargeOffReasons),
|
||||||
|
loanProductDetails.getChargeOffReasonToExpenseAccountMappings().get(0).getChargeOffReasonCodeValue().getId());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateLoanProductWithInvalidGLAccount() {
|
public void testCreateLoanProductWithInvalidGLAccount() {
|
||||||
final String creationBusinessDay = "15 January 2023";
|
runAt("15 January 2023", () -> {
|
||||||
runAt(creationBusinessDay, () -> {
|
|
||||||
try {
|
try {
|
||||||
Integer chargeOffReasons = createChargeOffReason();
|
Integer chargeOffReasons = createChargeOffReason();
|
||||||
loanTransactionHelper.createLoanProduct(loanProductsRequest(Long.valueOf(chargeOffReasons), 9999L));
|
loanTransactionHelper.createLoanProduct(loanProductsRequest(Long.valueOf(chargeOffReasons), -1L));
|
||||||
} catch (CallFailedRuntimeException e) {
|
} catch (CallFailedRuntimeException e) {
|
||||||
Assertions.assertTrue(e.getMessage().contains("validation.msg.glaccount.not.found"));
|
Assertions.assertTrue(e.getMessage().contains("validation.msg.glaccount.not.found"));
|
||||||
}
|
}
|
||||||
@@ -120,10 +91,9 @@ public class LoanProductChargeOffReasonMappingsTest extends BaseLoanIntegrationT
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateLoanProductWithInvalidChargeOffReason() {
|
public void testCreateLoanProductWithInvalidChargeOffReason() {
|
||||||
final String creationBusinessDay = "15 January 2023";
|
runAt("15 January 2023", () -> {
|
||||||
runAt(creationBusinessDay, () -> {
|
|
||||||
try {
|
try {
|
||||||
loanTransactionHelper.createLoanProduct(loanProductsRequest(1L, 12L));
|
loanTransactionHelper.createLoanProduct(loanProductsRequest(-1L, expenseAccount.getAccountID().longValue()));
|
||||||
} catch (CallFailedRuntimeException e) {
|
} catch (CallFailedRuntimeException e) {
|
||||||
Assertions.assertTrue(e.getMessage().contains("validation.msg.chargeoffreason.invalid"));
|
Assertions.assertTrue(e.getMessage().contains("validation.msg.chargeoffreason.invalid"));
|
||||||
}
|
}
|
||||||
@@ -141,11 +111,8 @@ public class LoanProductChargeOffReasonMappingsTest extends BaseLoanIntegrationT
|
|||||||
List<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = new ArrayList<>();
|
List<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = new ArrayList<>();
|
||||||
List<GetLoanFeeToIncomeAccountMappings> feeToIncomeAccountMappings = new ArrayList<>();
|
List<GetLoanFeeToIncomeAccountMappings> feeToIncomeAccountMappings = new ArrayList<>();
|
||||||
|
|
||||||
List<PostChargeOffReasonsToExpenseMappings> chargeOffReasonsToExpenseMappings = new ArrayList<>();
|
List<PostChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings = createPostChargeOffReasonToExpenseAccountMappings(
|
||||||
PostChargeOffReasonsToExpenseMappings getChargeOffReasonsToExpenseMappings = new PostChargeOffReasonsToExpenseMappings();
|
chargeOffReasonId, glAccountId);
|
||||||
getChargeOffReasonsToExpenseMappings.setChargeOffReasonCodeValueId(chargeOffReasonId);
|
|
||||||
getChargeOffReasonsToExpenseMappings.setExpenseGLAccountId(glAccountId);
|
|
||||||
chargeOffReasonsToExpenseMappings.add(getChargeOffReasonsToExpenseMappings);
|
|
||||||
|
|
||||||
List<GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings = new ArrayList<>();
|
List<GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings = new ArrayList<>();
|
||||||
GetLoanPaymentChannelToFundSourceMappings loanPaymentChannelToFundSourceMappings = new GetLoanPaymentChannelToFundSourceMappings();
|
GetLoanPaymentChannelToFundSourceMappings loanPaymentChannelToFundSourceMappings = new GetLoanPaymentChannelToFundSourceMappings();
|
||||||
@@ -248,7 +215,8 @@ public class LoanProductChargeOffReasonMappingsTest extends BaseLoanIntegrationT
|
|||||||
.delinquencyBucketId(delinquencyBucketId.longValue())//
|
.delinquencyBucketId(delinquencyBucketId.longValue())//
|
||||||
.paymentChannelToFundSourceMappings(paymentChannelToFundSourceMappings)//
|
.paymentChannelToFundSourceMappings(paymentChannelToFundSourceMappings)//
|
||||||
.penaltyToIncomeAccountMappings(penaltyToIncomeAccountMappings)//
|
.penaltyToIncomeAccountMappings(penaltyToIncomeAccountMappings)//
|
||||||
.chargeOffReasonsToExpenseMappings(chargeOffReasonsToExpenseMappings).feeToIncomeAccountMappings(feeToIncomeAccountMappings)//
|
.chargeOffReasonToExpenseAccountMappings(chargeOffReasonToExpenseAccountMappings)
|
||||||
|
.feeToIncomeAccountMappings(feeToIncomeAccountMappings)//
|
||||||
.isInterestRecalculationEnabled(true)//
|
.isInterestRecalculationEnabled(true)//
|
||||||
.preClosureInterestCalculationStrategy(1)//
|
.preClosureInterestCalculationStrategy(1)//
|
||||||
.rescheduleStrategyMethod(3)//
|
.rescheduleStrategyMethod(3)//
|
||||||
@@ -258,6 +226,17 @@ public class LoanProductChargeOffReasonMappingsTest extends BaseLoanIntegrationT
|
|||||||
.allowPartialPeriodInterestCalcualtion(false);//
|
.allowPartialPeriodInterestCalcualtion(false);//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static List<PostChargeOffReasonToExpenseAccountMappings> createPostChargeOffReasonToExpenseAccountMappings(
|
||||||
|
Long chargeOffReasonId, Long glAccountId) {
|
||||||
|
List<PostChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings = new ArrayList<>();
|
||||||
|
PostChargeOffReasonToExpenseAccountMappings chargeOffReasonToExpenseAccountMapping = new PostChargeOffReasonToExpenseAccountMappings();
|
||||||
|
chargeOffReasonToExpenseAccountMapping.setChargeOffReasonCodeValueId(chargeOffReasonId);
|
||||||
|
chargeOffReasonToExpenseAccountMapping.setExpenseGLAccountId(glAccountId);
|
||||||
|
chargeOffReasonToExpenseAccountMappings.add(chargeOffReasonToExpenseAccountMapping);
|
||||||
|
return chargeOffReasonToExpenseAccountMappings;
|
||||||
|
}
|
||||||
|
|
||||||
private Integer createChargeOffReason() {
|
private Integer createChargeOffReason() {
|
||||||
Integer chargeOffReasonId;
|
Integer chargeOffReasonId;
|
||||||
HashMap<String, Object> codes = CodeHelper.getCodeByName(requestSpec, responseSpec, CODE_VALUE_NAME);
|
HashMap<String, Object> codes = CodeHelper.getCodeByName(requestSpec, responseSpec, CODE_VALUE_NAME);
|
||||||
|
|||||||
+7
-7
@@ -108,7 +108,7 @@ public class LoanProductTestBuilder {
|
|||||||
|
|
||||||
private List<Map<String, Long>> feeToIncomeAccountMappings = null;
|
private List<Map<String, Long>> feeToIncomeAccountMappings = null;
|
||||||
private List<Map<String, Long>> penaltyToIncomeAccountMappings = null;
|
private List<Map<String, Long>> penaltyToIncomeAccountMappings = null;
|
||||||
private List<Map<String, Long>> chargeOffReasonsToExpenseMappings = null;
|
private List<Map<String, Long>> chargeOffReasonToExpenseAccountMappings = null;
|
||||||
private Account feeAndPenaltyAssetAccount;
|
private Account feeAndPenaltyAssetAccount;
|
||||||
|
|
||||||
private Boolean multiDisburseLoan = false;
|
private Boolean multiDisburseLoan = false;
|
||||||
@@ -306,8 +306,8 @@ public class LoanProductTestBuilder {
|
|||||||
map.put("penaltyToIncomeAccountMappings", this.penaltyToIncomeAccountMappings);
|
map.put("penaltyToIncomeAccountMappings", this.penaltyToIncomeAccountMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.chargeOffReasonsToExpenseMappings != null) {
|
if (this.chargeOffReasonToExpenseAccountMappings != null) {
|
||||||
map.put("chargeOffReasonsToExpenseMappings", this.chargeOffReasonsToExpenseMappings);
|
map.put("chargeOffReasonToExpenseAccountMappings", this.chargeOffReasonToExpenseAccountMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.dueDaysForRepaymentEvent != null) {
|
if (this.dueDaysForRepaymentEvent != null) {
|
||||||
@@ -812,14 +812,14 @@ public class LoanProductTestBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoanProductTestBuilder withChargeOffReasonsToExpenseMappings(final Long reasonId, final Long accountId) {
|
public LoanProductTestBuilder withchargeOffReasonToExpenseAccountMappings(final Long reasonId, final Long accountId) {
|
||||||
if (this.chargeOffReasonsToExpenseMappings == null) {
|
if (this.chargeOffReasonToExpenseAccountMappings == null) {
|
||||||
this.chargeOffReasonsToExpenseMappings = new ArrayList<>();
|
this.chargeOffReasonToExpenseAccountMappings = new ArrayList<>();
|
||||||
}
|
}
|
||||||
Map<String, Long> newMap = new HashMap<>();
|
Map<String, Long> newMap = new HashMap<>();
|
||||||
newMap.put("chargeOffReasonCodeValueId", reasonId);
|
newMap.put("chargeOffReasonCodeValueId", reasonId);
|
||||||
newMap.put("expenseGLAccountId", accountId);
|
newMap.put("expenseGLAccountId", accountId);
|
||||||
this.chargeOffReasonsToExpenseMappings.add(newMap);
|
this.chargeOffReasonToExpenseAccountMappings.add(newMap);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user