Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FINERACT-1806: fetch loan product details must return the chargeoffreason mapping #4187

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import java.util.List;
import java.util.Map;
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeOffReasonToGLAccountMapper;
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;

Expand All @@ -46,4 +47,6 @@ public interface ProductToGLAccountMappingReadPlatformService {
List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForShareProduct(Long productId);

List<ChargeToGLAccountMapper> fetchFeeToIncomeAccountMappingsForShareProduct(Long productId);

List<ChargeOffReasonToGLAccountMapper> fetchChargeOffReasonMappingsForLoanProduct(Long loanProductId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@
import org.apache.fineract.accounting.common.AccountingRuleType;
import org.apache.fineract.accounting.common.AccountingValidations;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeOffReasonToGLAccountMapper;
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
import org.apache.fineract.portfolio.PortfolioProductType;
import org.apache.fineract.portfolio.charge.data.ChargeData;
Expand All @@ -59,10 +61,11 @@ private static final class ProductToGLAccountMappingMapper implements RowMapper<
public String schema() {
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,pt.value as paymentTypeValue, mapping.charge_id as chargeId, charge.is_penalty as penalty, "
+ " charge.name as chargeName "
+ " mapping.payment_type as paymentTypeId,pt.value as paymentTypeValue, mapping.charge_id as chargeId, mapping.charge_off_reason_id as chargeOffReasonId, charge.is_penalty as penalty, "
+ " charge.name as chargeName, codeValue.code_value as codeValueName, codeValue.code_description as codeDescription, codeValue.order_position as orderPosition, codeValue.is_active as isActive, codeValue.is_mandatory as isMandatory "
+ " 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 acc_gl_account as glaccount on mapping.gl_account_id = glaccount.id "
+ " left join m_code_value as codeValue on mapping.charge_off_reason_id = codeValue.id "
+ " left join m_payment_type pt on mapping.payment_type=pt.id" + " where mapping.product_type= ? ";
}

Expand All @@ -81,6 +84,12 @@ public Map<String, Object> mapRow(final ResultSet rs, @SuppressWarnings("unused"
final String glCode = rs.getString("code");
final String chargeName = rs.getString("chargeName");
final Boolean penalty = rs.getBoolean("penalty");
final Integer chargeOffReasonId = rs.getInt("chargeOffReasonId");
final String codeValue = rs.getString("codeValueName");
final String codeDescription = rs.getString("codeDescription");
final Integer orderPosition = rs.getInt("orderPosition");
final Integer isActive = rs.getInt("isActive");
final Integer isMandatory = rs.getInt("isMandatory");

final Map<String, Object> loanProductToGLAccountMap = new LinkedHashMap<>(5);
loanProductToGLAccountMap.put("id", id);
Expand All @@ -95,6 +104,12 @@ public Map<String, Object> mapRow(final ResultSet rs, @SuppressWarnings("unused"
loanProductToGLAccountMap.put("penalty", penalty);
loanProductToGLAccountMap.put("glAccountName", glAccountName);
loanProductToGLAccountMap.put("glCode", glCode);
loanProductToGLAccountMap.put("chargeOffReasonId", chargeOffReasonId);
loanProductToGLAccountMap.put("codeValue", codeValue);
loanProductToGLAccountMap.put("codeDescription", codeDescription);
loanProductToGLAccountMap.put("orderPosition", orderPosition);
loanProductToGLAccountMap.put("isActive", isActive);
loanProductToGLAccountMap.put("isMandatory", isMandatory);
return loanProductToGLAccountMap;
}
}
Expand Down Expand Up @@ -342,6 +357,40 @@ private List<ChargeToGLAccountMapper> fetchChargeToIncomeAccountMappings(final P
return chargeToGLAccountMappers;
}

private List<ChargeOffReasonToGLAccountMapper> fetchChargeOffReasonMappings(final PortfolioProductType portfolioProductType,
final Long loanProductId) {
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
String sql = "select " + rm.schema() + " and product_id = ? and mapping.charge_off_reason_id is not null";

final List<Map<String, Object>> chargeOffReasonMappingsList = this.jdbcTemplate.query(sql, rm, // NOSONAR
new Object[] { portfolioProductType.getValue(), loanProductId });
List<ChargeOffReasonToGLAccountMapper> chargeOffReasonToGLAccountMappers = null;
for (final Map<String, Object> chargeOffReasonMap : chargeOffReasonMappingsList) {
if (chargeOffReasonToGLAccountMappers == null) {
chargeOffReasonToGLAccountMappers = new ArrayList<>();
}
final Long glAccountId = (Long) chargeOffReasonMap.get("glAccountId");
final String glAccountName = (String) chargeOffReasonMap.get("glAccountName");
final String glCode = (String) chargeOffReasonMap.get("glCode");
final GLAccountData chargeOffExpenseAccount = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
final Integer chargeOffReasonId = (Integer) chargeOffReasonMap.get("chargeOffReasonId");
final String codeValue = (String) chargeOffReasonMap.get("codeValue");
final String codeDescription = (String) chargeOffReasonMap.get("codeDescription");
final Integer orderPosition = (Integer) chargeOffReasonMap.get("orderPosition");
final Integer isActive = (Integer) chargeOffReasonMap.get("isActive");
final Integer isMandatory = (Integer) chargeOffReasonMap.get("isMandatory");
final boolean active = isActive != null && isActive == 1;
final boolean mandatory = isMandatory != null && isMandatory == 1;
final CodeValueData chargeOffReasonsCodeValue = CodeValueData.builder().id(Long.valueOf(chargeOffReasonId)).name(codeValue)
.description(codeDescription).position(orderPosition).active(active).mandatory(mandatory).build();

final ChargeOffReasonToGLAccountMapper chargeOffReasonToGLAccountMapper = new ChargeOffReasonToGLAccountMapper()
.setChargeOffReasonsCodeValue(chargeOffReasonsCodeValue).setChargeOffExpenseAccount(chargeOffExpenseAccount);
chargeOffReasonToGLAccountMappers.add(chargeOffReasonToGLAccountMapper);
}
return chargeOffReasonToGLAccountMappers;
}

@Override
public Map<String, Object> fetchAccountMappingDetailsForShareProduct(Long productId, Integer accountingType) {

Expand Down Expand Up @@ -388,6 +437,11 @@ public List<ChargeToGLAccountMapper> fetchFeeToIncomeAccountMappingsForShareProd
return fetchChargeToIncomeAccountMappings(PortfolioProductType.SHARES, productId, false);
}

@Override
public List<ChargeOffReasonToGLAccountMapper> fetchChargeOffReasonMappingsForLoanProduct(Long loanProductId) {
return fetchChargeOffReasonMappings(PortfolioProductType.LOAN, loanProductId);
}

private Map<String, Object> setAccrualPeriodicSavingsProductToGLAccountMaps(
final List<Map<String, Object>> listOfProductToGLAccountMaps) {
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.accounting.producttoaccountmapping.data;

import java.io.Serializable;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;

@Data
@NoArgsConstructor
@Accessors(chain = true)
public class ChargeOffReasonToGLAccountMapper implements Serializable {

private static final long serialVersionUID = 1L;
private CodeValueData chargeOffReasonsCodeValue;
private GLAccountData chargeOffExpenseAccount;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
package org.apache.fineract.infrastructure.codes.data;

import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
Expand All @@ -28,6 +30,8 @@
*/
@Data
@NoArgsConstructor
@Builder
@AllArgsConstructor
@Accessors(chain = true)
public class CodeValueData implements Serializable {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.fineract.accounting.common.AccountingEnumerations;
import org.apache.fineract.accounting.common.AccountingRuleType;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeOffReasonToGLAccountMapper;
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
Expand Down Expand Up @@ -151,7 +152,7 @@ public class LoanProductData implements Serializable {
private Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings;
private Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings;
private Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings;
private List<ChargeToGLAccountMapper> chargeOffReasonsToExpenseMappings;
private List<ChargeOffReasonToGLAccountMapper> chargeOffReasonToGLAccountMappings;
private final boolean enableAccrualActivityPosting;

// rates
Expand Down Expand Up @@ -733,11 +734,13 @@ public static LoanProductData loanProductWithFloatingRates(final Long id, final
public static LoanProductData withAccountingDetails(final LoanProductData productData, final Map<String, Object> accountingMappings,
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
final Collection<ChargeToGLAccountMapper> feeToGLAccountMappings,
final Collection<ChargeToGLAccountMapper> penaltyToGLAccountMappings) {
final Collection<ChargeToGLAccountMapper> penaltyToGLAccountMappings,
final List<ChargeOffReasonToGLAccountMapper> chargeOffReasonToGLAccountMappings) {
productData.accountingMappings = accountingMappings;
productData.paymentChannelToFundSourceMappings = paymentChannelToFundSourceMappings;
productData.feeToIncomeAccountMappings = feeToGLAccountMappings;
productData.penaltyToIncomeAccountMappings = penaltyToGLAccountMappings;
productData.chargeOffReasonToGLAccountMappings = chargeOffReasonToGLAccountMappings;
return productData;
}

Expand Down Expand Up @@ -854,7 +857,7 @@ public LoanProductData(final Long id, final String name, final String shortName,
this.paymentChannelToFundSourceMappings = null;
this.feeToIncomeAccountMappings = null;
this.penaltyToIncomeAccountMappings = null;
this.chargeOffReasonsToExpenseMappings = null;
this.chargeOffReasonToGLAccountMappings = null;
this.valueConditionTypeOptions = null;
this.principalVariationsForBorrowerCycle = principalVariations;
this.interestRateVariationsForBorrowerCycle = interestRateVariations;
Expand Down Expand Up @@ -994,7 +997,7 @@ public LoanProductData(final LoanProductData productData, final Collection<Charg
this.paymentChannelToFundSourceMappings = productData.paymentChannelToFundSourceMappings;
this.feeToIncomeAccountMappings = productData.feeToIncomeAccountMappings;
this.penaltyToIncomeAccountMappings = productData.penaltyToIncomeAccountMappings;
this.chargeOffReasonsToExpenseMappings = productData.chargeOffReasonsToExpenseMappings;
this.chargeOffReasonToGLAccountMappings = productData.chargeOffReasonToGLAccountMappings;

this.chargeOptions = chargeOptions;
this.penaltyOptions = penaltyOptions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import lombok.RequiredArgsConstructor;
import org.apache.fineract.accounting.common.AccountingDropdownReadPlatformService;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeOffReasonToGLAccountMapper;
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
import org.apache.fineract.accounting.producttoaccountmapping.service.ProductToGLAccountMappingReadPlatformService;
Expand Down Expand Up @@ -336,7 +337,7 @@ private String getLoanProductDetails(Long productId, UriInfo uriInfo) {
Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings;
Collection<ChargeToGLAccountMapper> feeToGLAccountMappings;
Collection<ChargeToGLAccountMapper> penaltyToGLAccountMappings;
List<ChargeToGLAccountMapper> chargeOffReasonsToExpenseMappings;
List<ChargeOffReasonToGLAccountMapper> chargeOffReasonToGLAccountMappings;
if (loanProduct.hasAccountingEnabled()) {
accountingMappings = this.accountMappingReadPlatformService.fetchAccountMappingDetailsForLoanProduct(productId,
loanProduct.getAccountingRule().getId().intValue());
Expand All @@ -345,8 +346,10 @@ private String getLoanProductDetails(Long productId, UriInfo uriInfo) {
feeToGLAccountMappings = this.accountMappingReadPlatformService.fetchFeeToGLAccountMappingsForLoanProduct(productId);
penaltyToGLAccountMappings = this.accountMappingReadPlatformService
.fetchPenaltyToIncomeAccountMappingsForLoanProduct(productId);
chargeOffReasonToGLAccountMappings = this.accountMappingReadPlatformService
.fetchChargeOffReasonMappingsForLoanProduct(productId);
loanProduct = LoanProductData.withAccountingDetails(loanProduct, accountingMappings, paymentChannelToFundSourceMappings,
feeToGLAccountMappings, penaltyToGLAccountMappings);
feeToGLAccountMappings, penaltyToGLAccountMappings, chargeOffReasonToGLAccountMappings);
}

if (settings.isTemplate()) {
Expand Down
Loading