Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ dependencyManagement {
mavenBom 'io.github.resilience4j:resilience4j-bom:2.4.0'
mavenBom 'org.testcontainers:testcontainers-bom:1.21.4'
mavenBom 'org.glassfish.jersey:jersey-bom:3.1.11'
mavenBom 'org.springframework.modulith:spring-modulith-bom:1.4.11'
}

dependencies {
Expand Down
5 changes: 5 additions & 0 deletions fineract-accounting/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ configurations {

apply from: 'dependencies.gradle'

test {
maxHeapSize = '2g'
jvmArgs += ['-XX:MaxMetaspaceSize=1g']
}
Comment thread
mansi75 marked this conversation as resolved.

// Configuration for the modernizer plugin
// https://github.com/andygoossens/gradle-modernizer-plugin
modernizer {
Expand Down
4 changes: 2 additions & 2 deletions fineract-accounting/dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/

dependencies {
// Never use "compile" scope, but make all dependencies either 'implementation', 'runtimeOnly' or 'testCompile'.
// Note that we never use 'api', because Fineract at least currently is a simple monolithic application ("WAR"), not a library.
Expand All @@ -25,7 +24,8 @@ dependencies {
// implementation dependencies are directly used (compiled against) in src/main (and src/test)
//
implementation(project(path: ':fineract-core'))
implementation(project(path: ':fineract-charge'))
testImplementation 'org.springframework.modulith:spring-modulith-core'
testImplementation("org.osgi:org.osgi.core:6.0.0")
implementation('org.apache.avro:avro')
implementation(
project(path: ':fineract-avro-schemas')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.portfolio.charge.domain.Charge;
import org.apache.fineract.portfolio.paymenttype.domain.PaymentType;

@Getter
Expand All @@ -54,9 +53,8 @@ public class ProductToGLAccountMapping extends AbstractPersistableCustom<Long> {
@JoinColumn(name = "payment_type", nullable = true)
private PaymentType paymentType;

@ManyToOne
@JoinColumn(name = "charge_id", nullable = true)
private Charge charge;
@Column(name = "charge_id", nullable = true)
private Long chargeId;

@Column(name = "product_type", nullable = true)
private int productType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ public interface ProductToGLAccountMappingRepository
ProductToGLAccountMapping findByProductIdAndProductTypeAndFinancialAccountTypeAndPaymentTypeId(Long productId, int productType,
int financialAccountType, Long paymentType);

@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId= :productId and mapping.productType= :productType and mapping.financialAccountType= :financialAccountType and mapping.charge.id= :chargeId")
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId= :productId and mapping.productType= :productType and mapping.financialAccountType= :financialAccountType and mapping.chargeId= :chargeId")
ProductToGLAccountMapping findProductIdAndProductTypeAndFinancialAccountTypeAndChargeId(@Param("productId") Long productId,
@Param("productType") int productType, @Param("financialAccountType") int financialAccountType,
@Param("chargeId") Long ChargeId);

@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=:financialAccountType and mapping.paymentType is NULL and mapping.charge is NULL and mapping.chargeOffReason is NULL and mapping.writeOffReason is NULL and mapping.capitalizedIncomeClassification is NULL and mapping.buydownFeeClassification is NULL")
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=:financialAccountType and mapping.paymentType is NULL and mapping.chargeId is NULL and mapping.chargeOffReason is NULL and mapping.writeOffReason is NULL and mapping.capitalizedIncomeClassification is NULL and mapping.buydownFeeClassification is NULL")
ProductToGLAccountMapping findCoreProductToFinAccountMapping(@Param("productId") Long productId, @Param("productType") int productType,
@Param("financialAccountType") int financialAccountType);

Expand All @@ -49,14 +49,14 @@ List<ProductToGLAccountMapping> findAllPaymentTypeToFundSourceMappings(@Param("p
/***
* The financial Account Type for income from interest will always be 4
***/
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=4 and mapping.charge is not NULL")
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=4 and mapping.chargeId is not NULL")
List<ProductToGLAccountMapping> findAllFeeToIncomeAccountMappings(@Param("productId") Long productId,
@Param("productType") int productType);

/***
* The financial Account Type for income from interest will always be 5
***/
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=5 and mapping.charge is not NULL")
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=5 and mapping.chargeId is not NULL")
List<ProductToGLAccountMapping> findAllPenaltyToIncomeAccountMappings(@Param("productId") Long productId,
@Param("productType") int productType);

Expand All @@ -77,19 +77,13 @@ List<ProductToGLAccountMapping> findAllWriteOffReasonsMappings(@Param("productId
ProductToGLAccountMapping findChargeOffReasonMapping(@Param("productId") Long productId, @Param("productType") Integer productType,
@Param("chargeOffReasonId") Long chargeOffReasonId);

@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 AND mapping.writeOffReason IS NULL AND mapping.capitalizedIncomeClassification is NULL AND mapping.buydownFeeClassification is NULL")
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId AND mapping.productType =:productType AND mapping.chargeId IS NULL AND mapping.paymentType IS NULL AND mapping.chargeOffReason IS NULL AND mapping.writeOffReason IS NULL AND mapping.capitalizedIncomeClassification is NULL AND mapping.buydownFeeClassification is NULL")
List<ProductToGLAccountMapping> findAllRegularMappings(@Param("productId") Long productId, @Param("productType") 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);

@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);

@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId AND mapping.productType =:productType AND mapping.charge.penalty = FALSE")
List<ProductToGLAccountMapping> findAllFeeMappings(@Param("productId") Long productId, @Param("productType") Integer productType);

@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.capitalizedIncomeClassification is not NULL")
List<ProductToGLAccountMapping> findAllCapitalizedIncomeClassificationsMappings(@Param("productId") Long productId,
@Param("productType") int productType);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* 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.service;

import java.util.Collection;
import java.util.List;
import org.apache.fineract.portfolio.charge.data.ChargeData;

public interface AccountingChargeReadService {

List<ChargeData> findChargesByIds(Collection<Long> chargeIds);
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.PortfolioProductType;
import org.apache.fineract.portfolio.charge.domain.Charge;
import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper;
import org.apache.fineract.portfolio.paymenttype.domain.PaymentType;
import org.apache.fineract.portfolio.paymenttype.domain.PaymentTypeRepository;
import org.apache.fineract.portfolio.paymenttype.exception.PaymentTypeNotFoundException;
Expand All @@ -65,7 +63,6 @@ public class ProductToGLAccountMappingHelper {
protected final GLAccountRepository accountRepository;
protected final ProductToGLAccountMappingRepository accountMappingRepository;
protected final FromJsonHelper fromApiJsonHelper;
private final ChargeRepositoryWrapper chargeRepositoryWrapper;
protected final GLAccountRepositoryWrapper accountRepositoryWrapper;
private final PaymentTypeRepository paymentTypeRepository;
private final CodeValueRepository codeValueRepository;
Expand Down Expand Up @@ -344,7 +341,7 @@ public void updateChargeToIncomeAccountMappings(final JsonCommand command, final
**/
else {
for (final ProductToGLAccountMapping chargeToIncomeAccountMapping : existingChargeToIncomeAccountMappings) {
final Long currentCharge = chargeToIncomeAccountMapping.getCharge().getId();
final Long currentCharge = chargeToIncomeAccountMapping.getChargeId();
existingCharges.add(currentCharge);
// update existing mappings (if required)
if (inputChargeToIncomeAccountMap.containsKey(currentCharge)) {
Expand Down Expand Up @@ -613,10 +610,6 @@ private void savePaymentChannelToFundSourceMapping(final Long productId, final L
*/
private void saveChargeToFundSourceMapping(final Long productId, final Long chargeId, final Long incomeAccountId,
final PortfolioProductType portfolioProductType, final boolean isPenalty) {
final Charge charge = this.chargeRepositoryWrapper.findOneWithNotFoundDetection(chargeId);

// TODO Vishwas: Need to validate if given charge is fee or Penalty
// based on input condition

GLAccount glAccount;
/**
Expand All @@ -635,7 +628,7 @@ private void saveChargeToFundSourceMapping(final Long productId, final Long char
}
final ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping().setGlAccount(glAccount).setProductId(productId)
.setProductType(portfolioProductType.getValue()).setFinancialAccountType(placeHolderAccountType.getValue())
.setCharge(charge);
.setChargeId(chargeId);
this.accountMappingRepository.saveAndFlush(accountMapping);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.accounting.common.AccountingConstants.AccrualAccountsForLoan;
Expand All @@ -36,6 +38,7 @@
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.glaccount.domain.GLAccount;
import org.apache.fineract.accounting.producttoaccountmapping.data.AdvancedMappingToExpenseAccountData;
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
import org.apache.fineract.accounting.producttoaccountmapping.data.ClassificationToGLAccountData;
Expand All @@ -56,6 +59,7 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product

private final ProductToGLAccountMappingRepository productToGLAccountMappingRepository;
private final CodeValueMapper codeValueMapper;
private final AccountingChargeReadService accountingChargeReadService;

@Override
public Map<String, Object> fetchAccountMappingDetailsForLoanProduct(final Long loanProductId, final Integer accountingType) {
Expand Down Expand Up @@ -258,18 +262,23 @@ public List<ChargeToGLAccountMapper> fetchPenaltyToIncomeAccountMappingsForSavin
private List<ChargeToGLAccountMapper> fetchChargeToIncomeAccountMappings(final PortfolioProductType portfolioProductType,
final Long loanProductId, final boolean penalty) {
final List<ProductToGLAccountMapping> mappings = penalty
? productToGLAccountMappingRepository.findAllPenaltyMappings(loanProductId, portfolioProductType.getValue())
: productToGLAccountMappingRepository.findAllFeeMappings(loanProductId, portfolioProductType.getValue());
? productToGLAccountMappingRepository.findAllPenaltyToIncomeAccountMappings(loanProductId, portfolioProductType.getValue())
: productToGLAccountMappingRepository.findAllFeeToIncomeAccountMappings(loanProductId, portfolioProductType.getValue());
if (mappings.isEmpty()) {
return null;
}

final List<Long> chargeIds = mappings.stream().map(ProductToGLAccountMapping::getChargeId).toList();
final Map<Long, ChargeData> chargesById = accountingChargeReadService.findChargesByIds(chargeIds).stream()
.collect(Collectors.toMap(ChargeData::getId, Function.identity()));

List<ChargeToGLAccountMapper> chargeToGLAccountMappers = mappings.isEmpty() ? null : new ArrayList<>();
final List<ChargeToGLAccountMapper> chargeToGLAccountMappers = new ArrayList<>();
for (final ProductToGLAccountMapping mapping : mappings) {
final GLAccountData gLAccountData = new GLAccountData().setId(mapping.getGlAccount().getId())
.setName(mapping.getGlAccount().getName()).setGlCode(mapping.getGlAccount().getGlCode());
final ChargeData chargeData = ChargeData.builder().id(mapping.getCharge().getId()).name(mapping.getCharge().getName())
.penalty(mapping.getCharge().isPenalty()).build();
final ChargeToGLAccountMapper chargeToGLAccountMapper = new ChargeToGLAccountMapper().setCharge(chargeData)
.setIncomeAccount(gLAccountData);
chargeToGLAccountMappers.add(chargeToGLAccountMapper);
final GLAccount glAccount = mapping.getGlAccount();
final GLAccountData gLAccountData = new GLAccountData().setId(glAccount.getId()).setName(glAccount.getName())
.setGlCode(glAccount.getGlCode());
chargeToGLAccountMappers
.add(new ChargeToGLAccountMapper().setCharge(chargesById.get(mapping.getChargeId())).setIncomeAccount(gLAccountData));
}
return chargeToGLAccountMappers;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.PortfolioProductType;
import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper;
import org.apache.fineract.portfolio.paymenttype.domain.PaymentTypeRepository;
import org.springframework.stereotype.Component;

Expand All @@ -42,16 +41,12 @@ public class SavingsProductToGLAccountMappingHelper extends ProductToGLAccountMa

public SavingsProductToGLAccountMappingHelper(final GLAccountRepository glAccountRepository,
final ProductToGLAccountMappingRepository glAccountMappingRepository, final FromJsonHelper fromApiJsonHelper,
final ChargeRepositoryWrapper chargeRepositoryWrapper, final GLAccountRepositoryWrapper accountRepositoryWrapper,
final PaymentTypeRepository paymentTypeRepository, final CodeValueRepository codeValueRepository) {
super(glAccountRepository, glAccountMappingRepository, fromApiJsonHelper, chargeRepositoryWrapper, accountRepositoryWrapper,
paymentTypeRepository, codeValueRepository);
final GLAccountRepositoryWrapper accountRepositoryWrapper, final PaymentTypeRepository paymentTypeRepository,
final CodeValueRepository codeValueRepository) {
super(glAccountRepository, glAccountMappingRepository, fromApiJsonHelper, accountRepositoryWrapper, paymentTypeRepository,
codeValueRepository);
}

/***
* Set of abstractions for saving Saving Products to GL Account Mappings
***/

public void saveSavingsToAssetAccountMapping(final JsonElement element, final String paramName, final Long productId,
final int placeHolderTypeId) {
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.ASSET, PortfolioProductType.SAVING);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.PortfolioProductType;
import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper;
import org.apache.fineract.portfolio.paymenttype.domain.PaymentTypeRepository;
import org.springframework.stereotype.Component;

Expand All @@ -41,10 +40,10 @@ public class ShareProductToGLAccountMappingHelper extends ProductToGLAccountMapp

public ShareProductToGLAccountMappingHelper(final GLAccountRepository glAccountRepository,
final ProductToGLAccountMappingRepository glAccountMappingRepository, final FromJsonHelper fromApiJsonHelper,
final ChargeRepositoryWrapper chargeRepositoryWrapper, final GLAccountRepositoryWrapper accountRepositoryWrapper,
final PaymentTypeRepository paymentTypeRepository, final CodeValueRepository codeValueRepository) {
super(glAccountRepository, glAccountMappingRepository, fromApiJsonHelper, chargeRepositoryWrapper, accountRepositoryWrapper,
paymentTypeRepository, codeValueRepository);
final GLAccountRepositoryWrapper accountRepositoryWrapper, final PaymentTypeRepository paymentTypeRepository,
final CodeValueRepository codeValueRepository) {
super(glAccountRepository, glAccountMappingRepository, fromApiJsonHelper, accountRepositoryWrapper, paymentTypeRepository,
codeValueRepository);
}

/***
Expand Down
Loading
Loading