FINERACT-1724: Move product account mapping packages to core
This commit is contained in:
+73
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* 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.domain;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.UniqueConstraint;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
||||
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
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@Entity
|
||||
@Table(name = "acc_product_mapping", uniqueConstraints = { @UniqueConstraint(columnNames = { "product_id", "product_type",
|
||||
"financial_account_type", "payment_type" }, name = "financial_action") })
|
||||
public class ProductToGLAccountMapping extends AbstractPersistableCustom {
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
@JoinColumn(name = "gl_account_id")
|
||||
private GLAccount glAccount;
|
||||
|
||||
@Column(name = "product_id", nullable = true)
|
||||
private Long productId;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "payment_type", nullable = true)
|
||||
private PaymentType paymentType;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "charge_id", nullable = true)
|
||||
private Charge charge;
|
||||
|
||||
@Column(name = "product_type", nullable = true)
|
||||
private int productType;
|
||||
|
||||
@Column(name = "financial_account_type", nullable = true)
|
||||
private int financialAccountType;
|
||||
|
||||
public static ProductToGLAccountMapping createNew(final GLAccount glAccount, final Long productId, final int productType,
|
||||
final int financialAccountType) {
|
||||
|
||||
return new ProductToGLAccountMapping().setGlAccount(glAccount).setProductId(productId).setProductType(productType)
|
||||
.setFinancialAccountType(financialAccountType);
|
||||
}
|
||||
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* 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.domain;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface ProductToGLAccountMappingRepository
|
||||
extends JpaRepository<ProductToGLAccountMapping, Long>, JpaSpecificationExecutor<ProductToGLAccountMapping> {
|
||||
|
||||
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")
|
||||
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")
|
||||
ProductToGLAccountMapping findCoreProductToFinAccountMapping(@Param("productId") Long productId, @Param("productType") int productType,
|
||||
@Param("financialAccountType") int financialAccountType);
|
||||
|
||||
/***
|
||||
* The financial Account Type for a fund source will always be an asset (1)
|
||||
***/
|
||||
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=1 and mapping.paymentType is not NULL")
|
||||
List<ProductToGLAccountMapping> findAllPaymentTypeToFundSourceMappings(@Param("productId") Long productId,
|
||||
@Param("productType") int productType);
|
||||
|
||||
/***
|
||||
* 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")
|
||||
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")
|
||||
List<ProductToGLAccountMapping> findAllPenaltyToIncomeAccountMappings(@Param("productId") Long productId,
|
||||
@Param("productType") int productType);
|
||||
|
||||
List<ProductToGLAccountMapping> findByProductIdAndProductType(Long productId, int productType);
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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.exception;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when product to GL account mapping are not found.
|
||||
*/
|
||||
public class ProductToGLAccountMappingInvalidException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public ProductToGLAccountMappingInvalidException(final String paramName, final String accountName, final Long accountId,
|
||||
final String actualAccountCategory, final String expectedAccountCategory) {
|
||||
super("error.msg." + paramName + ".invalid.account.type",
|
||||
"Passed in GLAccount " + paramName + " with Id " + accountId + "maps to the account " + accountName + " of type "
|
||||
+ actualAccountCategory + ", the expected account type was one among" + expectedAccountCategory,
|
||||
paramName, accountId, accountName, actualAccountCategory, expectedAccountCategory);
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.exception;
|
||||
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||
|
||||
/**
|
||||
* A {@link RuntimeException} thrown when product to GL account mapping are not found.
|
||||
*/
|
||||
public class ProductToGLAccountMappingNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public ProductToGLAccountMappingNotFoundException(final PortfolioProductType type, final Long productId, final String accountType) {
|
||||
super("error.msg.productToAccountMapping.not.found", "Mapping for product of type " + type.toString() + " with Id " + productId
|
||||
+ " does not exist for an account of type " + accountType, type.toString(), productId, accountType);
|
||||
}
|
||||
}
|
||||
+291
@@ -0,0 +1,291 @@
|
||||
/**
|
||||
* 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.serialization;
|
||||
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_PRODUCT_RESOURCE_NAME;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accountingRuleParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.isDormancyTrackingActiveParamName;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.LoanProductAccountingParams;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.SavingProductAccountingParams;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.SharesProductAccountingParams;
|
||||
import org.apache.fineract.accounting.common.AccountingRuleType;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.service.ProductToGLAccountMappingWritePlatformService;
|
||||
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.portfolio.savings.DepositAccountType;
|
||||
import org.apache.fineract.portfolio.shareproducts.constants.ShareProductApiConstants;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* TODO Vishwas find a better approach for validation
|
||||
*
|
||||
* Currently, validation of the passed in JSON is done before calling save or update method on the target resource (in
|
||||
* our case the loan Product)
|
||||
*
|
||||
* However, in the case of a loan product it would be difficult to validate the passed in JSON for valid LoanProduct to
|
||||
* {@link GLAccount} mappings during update because of the following scenario
|
||||
*
|
||||
* The accounting rule type may be changed in the update command, so we would have to validate if all required account
|
||||
* heads for a particular account type have been passed in (would be different for CASH and Accrual based). However,
|
||||
* till we have access to the domain object it would not be possible to detect if an accounting rule has actually been
|
||||
* changed
|
||||
*
|
||||
* Hence, method {@link #validateForLoanProductCreate(String)} from this class is called separately for validation only
|
||||
* if an accounting rule change is detected by {@link ProductToGLAccountMappingWritePlatformService}
|
||||
*
|
||||
* Also, the class is probably named wrong (*FromApiJsonDeserializer) should probably be named as (*Validator) instead
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public final class ProductToGLAccountMappingFromApiJsonDeserializer {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
public void validateForLoanProductCreate(final String json) {
|
||||
if (StringUtils.isBlank(json)) {
|
||||
throw new InvalidJsonException();
|
||||
}
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loanproduct");
|
||||
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
// accounting related data validation
|
||||
final Integer accountingRuleType = this.fromApiJsonHelper.extractIntegerNamed("accountingRule", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("accountingRule").value(accountingRuleType).notNull().inMinMaxRange(1, 4);
|
||||
|
||||
if (isCashBasedAccounting(accountingRuleType) || isAccrualBasedAccounting(accountingRuleType)) {
|
||||
|
||||
final Long fundAccountId = this.fromApiJsonHelper.extractLongNamed(LoanProductAccountingParams.FUND_SOURCE.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.FUND_SOURCE.getValue()).value(fundAccountId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
|
||||
final Long loanPortfolioAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(LoanProductAccountingParams.LOAN_PORTFOLIO.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.LOAN_PORTFOLIO.getValue()).value(loanPortfolioAccountId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
final Long incomeFromInterestId = this.fromApiJsonHelper
|
||||
.extractLongNamed(LoanProductAccountingParams.INTEREST_ON_LOANS.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.INTEREST_ON_LOANS.getValue()).value(incomeFromInterestId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
final Long incomeFromFeeId = this.fromApiJsonHelper.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_FEES.getValue(),
|
||||
element);
|
||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_FEES.getValue()).value(incomeFromFeeId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
|
||||
final Long incomeFromPenaltyId = this.fromApiJsonHelper
|
||||
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_PENALTIES.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_PENALTIES.getValue()).value(incomeFromPenaltyId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
final Long incomeFromRecoveryAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_RECOVERY.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_RECOVERY.getValue())
|
||||
.value(incomeFromRecoveryAccountId).notNull().integerGreaterThanZero();
|
||||
|
||||
final Long writeOffAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(LoanProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.LOSSES_WRITTEN_OFF.getValue()).value(writeOffAccountId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
final Long overpaymentAccountId = this.fromApiJsonHelper.extractLongNamed(LoanProductAccountingParams.OVERPAYMENT.getValue(),
|
||||
element);
|
||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.OVERPAYMENT.getValue()).value(overpaymentAccountId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
|
||||
final Long transfersInSuspenseAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(LoanProductAccountingParams.TRANSFERS_SUSPENSE.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.TRANSFERS_SUSPENSE.getValue())
|
||||
.value(transfersInSuspenseAccountId).notNull().integerGreaterThanZero();
|
||||
|
||||
}
|
||||
|
||||
if (isAccrualBasedAccounting(accountingRuleType)) {
|
||||
|
||||
final Long receivableInterestAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(LoanProductAccountingParams.INTEREST_RECEIVABLE.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.INTEREST_RECEIVABLE.getValue())
|
||||
.value(receivableInterestAccountId).notNull().integerGreaterThanZero();
|
||||
|
||||
final Long receivableFeeAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(LoanProductAccountingParams.FEES_RECEIVABLE.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.FEES_RECEIVABLE.getValue()).value(receivableFeeAccountId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
final Long receivablePenaltyAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(LoanProductAccountingParams.PENALTIES_RECEIVABLE.getValue(), element);
|
||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.PENALTIES_RECEIVABLE.getValue())
|
||||
.value(receivablePenaltyAccountId).notNull().integerGreaterThanZero();
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForSavingsProductCreate(final String json, DepositAccountType accountType) {
|
||||
if (StringUtils.isBlank(json)) {
|
||||
throw new InvalidJsonException();
|
||||
}
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(SAVINGS_PRODUCT_RESOURCE_NAME);
|
||||
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
// accounting related data validation
|
||||
final Integer accountingRuleType = this.fromApiJsonHelper.extractIntegerNamed(accountingRuleParamName, element,
|
||||
Locale.getDefault());
|
||||
baseDataValidator.reset().parameter(accountingRuleParamName).value(accountingRuleType).notNull().inMinMaxRange(1, 3);
|
||||
|
||||
if (isCashBasedAccounting(accountingRuleType)) {
|
||||
|
||||
final Long savingsControlAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(SavingProductAccountingParams.SAVINGS_CONTROL.getValue(), element);
|
||||
baseDataValidator.reset().parameter(SavingProductAccountingParams.SAVINGS_CONTROL.getValue()).value(savingsControlAccountId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
final Long savingsReferenceAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(), element);
|
||||
baseDataValidator.reset().parameter(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue()).value(savingsReferenceAccountId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
final Long transfersInSuspenseAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(), element);
|
||||
baseDataValidator.reset().parameter(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue())
|
||||
.value(transfersInSuspenseAccountId).notNull().integerGreaterThanZero();
|
||||
|
||||
final Long interestOnSavingsAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(), element);
|
||||
baseDataValidator.reset().parameter(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue())
|
||||
.value(interestOnSavingsAccountId).notNull().integerGreaterThanZero();
|
||||
|
||||
final Long incomeFromFeeId = this.fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_FEES.getValue(),
|
||||
element);
|
||||
baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_FEES.getValue()).value(incomeFromFeeId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
|
||||
final Long incomeFromPenaltyId = this.fromApiJsonHelper
|
||||
.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(), element);
|
||||
baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue()).value(incomeFromPenaltyId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
final Boolean isDormancyTrackingActive = this.fromApiJsonHelper.extractBooleanNamed(isDormancyTrackingActiveParamName, element);
|
||||
if (null != isDormancyTrackingActive && isDormancyTrackingActive) {
|
||||
final Long escheatLiabilityId = this.fromApiJsonHelper
|
||||
.extractLongNamed(SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue(), element);
|
||||
baseDataValidator.reset().parameter(SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue()).value(escheatLiabilityId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
}
|
||||
|
||||
if (!accountType.equals(DepositAccountType.RECURRING_DEPOSIT) && !accountType.equals(DepositAccountType.FIXED_DEPOSIT)) {
|
||||
final Long overdraftAccount = this.fromApiJsonHelper
|
||||
.extractLongNamed(SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), element);
|
||||
baseDataValidator.reset().parameter(SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue())
|
||||
.value(overdraftAccount).notNull().integerGreaterThanZero();
|
||||
|
||||
final Long incomeFromInterest = this.fromApiJsonHelper
|
||||
.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue(), element);
|
||||
baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue()).value(incomeFromInterest)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
final Long writtenOff = this.fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(),
|
||||
element);
|
||||
baseDataValidator.reset().parameter(SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue()).value(writtenOff).notNull()
|
||||
.integerGreaterThanZero();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForShareProductCreate(final String json) {
|
||||
if (StringUtils.isBlank(json)) {
|
||||
throw new InvalidJsonException();
|
||||
}
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(ShareProductApiConstants.SHARE_PRODUCT_RESOURCE_NAME);
|
||||
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
// accounting related data validation
|
||||
final Integer accountingRuleType = this.fromApiJsonHelper.extractIntegerNamed(accountingRuleParamName, element,
|
||||
Locale.getDefault());
|
||||
baseDataValidator.reset().parameter(accountingRuleParamName).value(accountingRuleType).notNull().inMinMaxRange(1, 3);
|
||||
|
||||
if (isCashBasedAccounting(accountingRuleType)) {
|
||||
|
||||
final Long shareReferenceId = this.fromApiJsonHelper.extractLongNamed(SharesProductAccountingParams.SHARES_REFERENCE.getValue(),
|
||||
element);
|
||||
baseDataValidator.reset().parameter(SharesProductAccountingParams.SHARES_REFERENCE.getValue()).value(shareReferenceId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
|
||||
final Long shareSuspenseId = this.fromApiJsonHelper.extractLongNamed(SharesProductAccountingParams.SHARES_SUSPENSE.getValue(),
|
||||
element);
|
||||
baseDataValidator.reset().parameter(SharesProductAccountingParams.SHARES_SUSPENSE.getValue()).value(shareSuspenseId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
|
||||
final Long incomeFromFeeAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(SharesProductAccountingParams.INCOME_FROM_FEES.getValue(), element);
|
||||
baseDataValidator.reset().parameter(SharesProductAccountingParams.INCOME_FROM_FEES.getValue()).value(incomeFromFeeAccountId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
|
||||
final Long shareEquityId = this.fromApiJsonHelper.extractLongNamed(SharesProductAccountingParams.SHARES_EQUITY.getValue(),
|
||||
element);
|
||||
baseDataValidator.reset().parameter(SharesProductAccountingParams.SHARES_EQUITY.getValue()).value(shareEquityId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private boolean isCashBasedAccounting(final Integer accountingRuleType) {
|
||||
return AccountingRuleType.CASH_BASED.getValue().equals(accountingRuleType);
|
||||
}
|
||||
|
||||
private boolean isAccrualBasedAccounting(final Integer accountingRuleType) {
|
||||
return AccountingRuleType.ACCRUAL_PERIODIC.getValue().equals(accountingRuleType)
|
||||
|| AccountingRuleType.ACCRUAL_UPFRONT.getValue().equals(accountingRuleType);
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||
dataValidationErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
+463
@@ -0,0 +1,463 @@
|
||||
/**
|
||||
* 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 com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForLoan;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.LoanProductAccountingParams;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepository;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepositoryWrapper;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMapping;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingInvalidException;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingNotFoundException;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
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.PaymentTypeRepositoryWrapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ProductToGLAccountMappingHelper {
|
||||
|
||||
protected static final List<GLAccountType> ASSET_LIABILITY_TYPES = List.of(GLAccountType.ASSET, GLAccountType.LIABILITY);
|
||||
|
||||
protected final GLAccountRepository accountRepository;
|
||||
protected final ProductToGLAccountMappingRepository accountMappingRepository;
|
||||
protected final FromJsonHelper fromApiJsonHelper;
|
||||
private final ChargeRepositoryWrapper chargeRepositoryWrapper;
|
||||
protected final GLAccountRepositoryWrapper accountRepositoryWrapper;
|
||||
private final PaymentTypeRepositoryWrapper paymentTypeRepositoryWrapper;
|
||||
|
||||
public void saveProductToAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||
final int placeHolderTypeId, final GLAccountType expectedAccountType, final PortfolioProductType portfolioProductType) {
|
||||
final Long accountId = this.fromApiJsonHelper.extractLongNamed(paramName, element);
|
||||
if (accountId != null) { // optional entries may be null
|
||||
final GLAccount glAccount = getAccountByIdAndType(paramName, expectedAccountType, accountId);
|
||||
|
||||
final ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping().setGlAccount(glAccount).setProductId(productId)
|
||||
.setProductType(portfolioProductType.getValue()).setFinancialAccountType(placeHolderTypeId);
|
||||
this.accountMappingRepository.saveAndFlush(accountMapping);
|
||||
}
|
||||
}
|
||||
|
||||
public void mergeProductToAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes,
|
||||
final GLAccountType expectedAccountType, final PortfolioProductType portfolioProductType) {
|
||||
final Long accountId = this.fromApiJsonHelper.extractLongNamed(paramName, element);
|
||||
|
||||
// get the existing product
|
||||
if (accountId != null) {
|
||||
final ProductToGLAccountMapping accountMapping = this.accountMappingRepository.findCoreProductToFinAccountMapping(productId,
|
||||
portfolioProductType.getValue(), accountTypeId);
|
||||
if (accountMapping == null) {
|
||||
ArrayList<String> optionalProductToGLAccountMappingEntries = new ArrayList<String>();
|
||||
optionalProductToGLAccountMappingEntries.add(LoanProductAccountingParams.GOODWILL_CREDIT.getValue());
|
||||
optionalProductToGLAccountMappingEntries.add(LoanProductAccountingParams.INCOME_FROM_CHARGE_OFF_INTEREST.getValue());
|
||||
optionalProductToGLAccountMappingEntries.add(LoanProductAccountingParams.INCOME_FROM_CHARGE_OFF_FEES.getValue());
|
||||
optionalProductToGLAccountMappingEntries.add(LoanProductAccountingParams.CHARGE_OFF_EXPENSE.getValue());
|
||||
optionalProductToGLAccountMappingEntries.add(LoanProductAccountingParams.CHARGE_OFF_FRAUD_EXPENSE.getValue());
|
||||
optionalProductToGLAccountMappingEntries.add(LoanProductAccountingParams.INCOME_FROM_CHARGE_OFF_PENALTY.getValue());
|
||||
optionalProductToGLAccountMappingEntries.add("incomeFromGoodwillCreditInterestAccountId");
|
||||
optionalProductToGLAccountMappingEntries.add("incomeFromGoodwillCreditFeesAccountId");
|
||||
optionalProductToGLAccountMappingEntries.add("incomeFromGoodwillCreditPenaltyAccountId");
|
||||
|
||||
if (optionalProductToGLAccountMappingEntries.contains(paramName)) {
|
||||
saveProductToAccountMapping(element, paramName, productId, accountTypeId, expectedAccountType, portfolioProductType);
|
||||
} else {
|
||||
throw new ProductToGLAccountMappingNotFoundException(portfolioProductType, productId, accountTypeName);
|
||||
}
|
||||
} else {
|
||||
if (!accountMapping.getGlAccount().getId().equals(accountId)) {
|
||||
final GLAccount glAccount = getAccountByIdAndType(paramName, expectedAccountType, accountId);
|
||||
changes.put(paramName, accountId);
|
||||
accountMapping.setGlAccount(glAccount);
|
||||
this.accountMappingRepository.saveAndFlush(accountMapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void createOrmergeProductToAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||
final int accountTypeId, final Map<String, Object> changes, final GLAccountType expectedAccountType,
|
||||
final PortfolioProductType portfolioProductType) {
|
||||
final Long accountId = this.fromApiJsonHelper.extractLongNamed(paramName, element);
|
||||
|
||||
// get the existing product
|
||||
if (accountId != null) {
|
||||
final ProductToGLAccountMapping accountMapping = this.accountMappingRepository.findCoreProductToFinAccountMapping(productId,
|
||||
portfolioProductType.getValue(), accountTypeId);
|
||||
if (accountMapping == null) {
|
||||
final GLAccount glAccount = getAccountByIdAndType(paramName, expectedAccountType, accountId);
|
||||
changes.put(paramName, accountId);
|
||||
ProductToGLAccountMapping newAccountMapping = new ProductToGLAccountMapping().setGlAccount(glAccount)
|
||||
.setProductId(productId).setProductType(portfolioProductType.getValue()).setFinancialAccountType(accountTypeId);
|
||||
this.accountMappingRepository.saveAndFlush(newAccountMapping);
|
||||
} else if (!accountMapping.getGlAccount().getId().equals(accountId)) {
|
||||
final GLAccount glAccount = getAccountByIdAndType(paramName, expectedAccountType, accountId);
|
||||
changes.put(paramName, accountId);
|
||||
accountMapping.setGlAccount(glAccount);
|
||||
this.accountMappingRepository.saveAndFlush(accountMapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the payment type to Fund source mappings for a particular product/product type (also populates the changes
|
||||
* array if passed in)
|
||||
*
|
||||
* @param command
|
||||
* @param element
|
||||
* @param productId
|
||||
* @param changes
|
||||
*/
|
||||
public void savePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||
final Map<String, Object> changes, final PortfolioProductType portfolioProductType) {
|
||||
final JsonArray paymentChannelMappingArray = this.fromApiJsonHelper
|
||||
.extractJsonArrayNamed(LoanProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element);
|
||||
if (paymentChannelMappingArray != null) {
|
||||
if (changes != null) {
|
||||
changes.put(LoanProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
|
||||
command.jsonFragment(LoanProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue()));
|
||||
}
|
||||
for (int i = 0; i < paymentChannelMappingArray.size(); i++) {
|
||||
final JsonObject jsonObject = paymentChannelMappingArray.get(i).getAsJsonObject();
|
||||
final Long paymentTypeId = jsonObject.get(LoanProductAccountingParams.PAYMENT_TYPE.getValue()).getAsLong();
|
||||
final Long paymentSpecificFundAccountId = jsonObject.get(LoanProductAccountingParams.FUND_SOURCE.getValue()).getAsLong();
|
||||
savePaymentChannelToFundSourceMapping(productId, paymentTypeId, paymentSpecificFundAccountId, portfolioProductType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the Charge to Income / Liability account mappings for a particular product/product type (also populates the
|
||||
* changes array if passed in)
|
||||
*
|
||||
* @param command
|
||||
* @param element
|
||||
* @param productId
|
||||
* @param changes
|
||||
*/
|
||||
public void saveChargesToGLAccountMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||
final Map<String, Object> changes, final PortfolioProductType portfolioProductType, final boolean isPenalty) {
|
||||
String arrayName;
|
||||
if (isPenalty) {
|
||||
arrayName = LoanProductAccountingParams.PENALTY_INCOME_ACCOUNT_MAPPING.getValue();
|
||||
} else {
|
||||
arrayName = LoanProductAccountingParams.FEE_INCOME_ACCOUNT_MAPPING.getValue();
|
||||
}
|
||||
|
||||
final JsonArray chargeToIncomeAccountMappingArray = this.fromApiJsonHelper.extractJsonArrayNamed(arrayName, element);
|
||||
if (chargeToIncomeAccountMappingArray != null) {
|
||||
if (changes != null) {
|
||||
changes.put(LoanProductAccountingParams.FEE_INCOME_ACCOUNT_MAPPING.getValue(),
|
||||
command.jsonFragment(LoanProductAccountingParams.FEE_INCOME_ACCOUNT_MAPPING.getValue()));
|
||||
}
|
||||
for (int i = 0; i < chargeToIncomeAccountMappingArray.size(); i++) {
|
||||
final JsonObject jsonObject = chargeToIncomeAccountMappingArray.get(i).getAsJsonObject();
|
||||
final Long chargeId = jsonObject.get(LoanProductAccountingParams.CHARGE_ID.getValue()).getAsLong();
|
||||
final Long incomeAccountId = jsonObject.get(LoanProductAccountingParams.INCOME_ACCOUNT_ID.getValue()).getAsLong();
|
||||
saveChargeToFundSourceMapping(productId, chargeId, incomeAccountId, portfolioProductType, isPenalty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param command
|
||||
* @param element
|
||||
* @param productId
|
||||
* @param changes
|
||||
*/
|
||||
public void updateChargeToIncomeAccountMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||
final Map<String, Object> changes, final PortfolioProductType portfolioProductType, final boolean isPenalty) {
|
||||
// find all existing payment Channel to Fund source Mappings
|
||||
List<ProductToGLAccountMapping> existingChargeToIncomeAccountMappings;
|
||||
String arrayFragmentName;
|
||||
|
||||
if (isPenalty) {
|
||||
existingChargeToIncomeAccountMappings = this.accountMappingRepository.findAllPenaltyToIncomeAccountMappings(productId,
|
||||
portfolioProductType.getValue());
|
||||
arrayFragmentName = LoanProductAccountingParams.PENALTY_INCOME_ACCOUNT_MAPPING.getValue();
|
||||
} else {
|
||||
existingChargeToIncomeAccountMappings = this.accountMappingRepository.findAllFeeToIncomeAccountMappings(productId,
|
||||
portfolioProductType.getValue());
|
||||
arrayFragmentName = LoanProductAccountingParams.FEE_INCOME_ACCOUNT_MAPPING.getValue();
|
||||
}
|
||||
|
||||
final JsonArray chargeToIncomeAccountMappingArray = this.fromApiJsonHelper.extractJsonArrayNamed(arrayFragmentName, element);
|
||||
/**
|
||||
* Variable stores a map representation of charges (key) and their associated income Id's (value) extracted from
|
||||
* the passed in Jsoncommand
|
||||
**/
|
||||
final Map<Long, Long> inputChargeToIncomeAccountMap = new HashMap<>();
|
||||
/***
|
||||
* Variable stores all charges which have already been mapped to Income Accounts in the system
|
||||
**/
|
||||
final Set<Long> existingCharges = new HashSet<>();
|
||||
if (chargeToIncomeAccountMappingArray != null) {
|
||||
if (changes != null) {
|
||||
changes.put(arrayFragmentName, command.jsonFragment(arrayFragmentName));
|
||||
}
|
||||
|
||||
for (int i = 0; i < chargeToIncomeAccountMappingArray.size(); i++) {
|
||||
final JsonObject jsonObject = chargeToIncomeAccountMappingArray.get(i).getAsJsonObject();
|
||||
final Long chargeId = jsonObject.get(LoanProductAccountingParams.CHARGE_ID.getValue()).getAsLong();
|
||||
final Long incomeAccountId = jsonObject.get(LoanProductAccountingParams.INCOME_ACCOUNT_ID.getValue()).getAsLong();
|
||||
inputChargeToIncomeAccountMap.put(chargeId, incomeAccountId);
|
||||
}
|
||||
|
||||
// If input map is empty, delete all existing mappings
|
||||
if (inputChargeToIncomeAccountMap.size() == 0) {
|
||||
this.accountMappingRepository.deleteAllInBatch(existingChargeToIncomeAccountMappings);
|
||||
} /**
|
||||
* Else, <br/>
|
||||
* update existing mappings OR <br/>
|
||||
* delete old mappings (which are already present, but not passed in as a part of Jsoncommand)<br/>
|
||||
* Create new mappings for charges that are passed in as a part of the Jsoncommand but not already present
|
||||
*
|
||||
**/
|
||||
else {
|
||||
for (final ProductToGLAccountMapping chargeToIncomeAccountMapping : existingChargeToIncomeAccountMappings) {
|
||||
final Long currentCharge = chargeToIncomeAccountMapping.getCharge().getId();
|
||||
existingCharges.add(currentCharge);
|
||||
// update existing mappings (if required)
|
||||
if (inputChargeToIncomeAccountMap.containsKey(currentCharge)) {
|
||||
final Long newGLAccountId = inputChargeToIncomeAccountMap.get(currentCharge);
|
||||
if (!newGLAccountId.equals(chargeToIncomeAccountMapping.getGlAccount().getId())) {
|
||||
final GLAccount glAccount;
|
||||
if (isPenalty) {
|
||||
glAccount = getAccountByIdAndType(LoanProductAccountingParams.INCOME_ACCOUNT_ID.getValue(),
|
||||
GLAccountType.INCOME, newGLAccountId);
|
||||
} else {
|
||||
List<GLAccountType> allowedAccountTypes = getAllowedAccountTypesForFeeMapping();
|
||||
glAccount = getAccountByIdAndType(LoanProductAccountingParams.INCOME_ACCOUNT_ID.getValue(),
|
||||
allowedAccountTypes, newGLAccountId);
|
||||
}
|
||||
chargeToIncomeAccountMapping.setGlAccount(glAccount);
|
||||
this.accountMappingRepository.saveAndFlush(chargeToIncomeAccountMapping);
|
||||
}
|
||||
} // deleted payment type
|
||||
else {
|
||||
this.accountMappingRepository.delete(chargeToIncomeAccountMapping);
|
||||
}
|
||||
}
|
||||
// create new mappings
|
||||
final Set<Long> incomingCharges = inputChargeToIncomeAccountMap.keySet();
|
||||
incomingCharges.removeAll(existingCharges);
|
||||
// incomingPaymentTypes now only contains the newly added
|
||||
// payment Type mappings
|
||||
for (final Long newCharge : incomingCharges) {
|
||||
final Long newGLAccountId = inputChargeToIncomeAccountMap.get(newCharge);
|
||||
saveChargeToFundSourceMapping(productId, newCharge, newGLAccountId, portfolioProductType, isPenalty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param command
|
||||
* @param element
|
||||
* @param productId
|
||||
* @param changes
|
||||
*/
|
||||
public void updatePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||
final Map<String, Object> changes, final PortfolioProductType portfolioProductType) {
|
||||
// find all existing payment Channel to Fund source Mappings
|
||||
final List<ProductToGLAccountMapping> existingPaymentChannelToFundSourceMappings = this.accountMappingRepository
|
||||
.findAllPaymentTypeToFundSourceMappings(productId, portfolioProductType.getValue());
|
||||
final JsonArray paymentChannelMappingArray = this.fromApiJsonHelper
|
||||
.extractJsonArrayNamed(LoanProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element);
|
||||
/**
|
||||
* Variable stores a map representation of Payment channels (key) and their fund sources (value) extracted from
|
||||
* the passed in Jsoncommand
|
||||
**/
|
||||
final Map<Long, Long> inputPaymentChannelFundSourceMap = new HashMap<>();
|
||||
/***
|
||||
* Variable stores all payment types which have already been mapped to Fund Sources in the system
|
||||
**/
|
||||
final Set<Long> existingPaymentTypes = new HashSet<>();
|
||||
if (paymentChannelMappingArray != null) {
|
||||
if (changes != null) {
|
||||
changes.put(LoanProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
|
||||
command.jsonFragment(LoanProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue()));
|
||||
}
|
||||
|
||||
for (int i = 0; i < paymentChannelMappingArray.size(); i++) {
|
||||
final JsonObject jsonObject = paymentChannelMappingArray.get(i).getAsJsonObject();
|
||||
final Long paymentTypeId = jsonObject.get(LoanProductAccountingParams.PAYMENT_TYPE.getValue()).getAsLong();
|
||||
final Long paymentSpecificFundAccountId = jsonObject.get(LoanProductAccountingParams.FUND_SOURCE.getValue()).getAsLong();
|
||||
inputPaymentChannelFundSourceMap.put(paymentTypeId, paymentSpecificFundAccountId);
|
||||
}
|
||||
|
||||
// If input map is empty, delete all existing mappings
|
||||
if (inputPaymentChannelFundSourceMap.size() == 0) {
|
||||
this.accountMappingRepository.deleteAllInBatch(existingPaymentChannelToFundSourceMappings);
|
||||
} /**
|
||||
* Else, <br/>
|
||||
* update existing mappings OR <br/>
|
||||
* delete old mappings (which re already present, but not passed in as a part of Jsoncommand)<br/>
|
||||
* Create new mappings for payment types that are passed in as a part of the Jsoncommand but not already
|
||||
* present
|
||||
*
|
||||
**/
|
||||
else {
|
||||
for (final ProductToGLAccountMapping existingPaymentChannelToFundSourceMapping : existingPaymentChannelToFundSourceMappings) {
|
||||
final Long currentPaymentChannelId = existingPaymentChannelToFundSourceMapping.getPaymentType().getId();
|
||||
existingPaymentTypes.add(currentPaymentChannelId);
|
||||
// update existing mappings (if required)
|
||||
if (inputPaymentChannelFundSourceMap.containsKey(currentPaymentChannelId)) {
|
||||
final Long newGLAccountId = inputPaymentChannelFundSourceMap.get(currentPaymentChannelId);
|
||||
if (!newGLAccountId.equals(existingPaymentChannelToFundSourceMapping.getGlAccount().getId())) {
|
||||
final GLAccount glAccount = getAccountById(LoanProductAccountingParams.FUND_SOURCE.getValue(), newGLAccountId);
|
||||
existingPaymentChannelToFundSourceMapping.setGlAccount(glAccount);
|
||||
this.accountMappingRepository.saveAndFlush(existingPaymentChannelToFundSourceMapping);
|
||||
}
|
||||
} // deleted payment type
|
||||
else {
|
||||
this.accountMappingRepository.delete(existingPaymentChannelToFundSourceMapping);
|
||||
}
|
||||
}
|
||||
// create new mappings
|
||||
final Set<Long> incomingPaymentTypes = inputPaymentChannelFundSourceMap.keySet();
|
||||
incomingPaymentTypes.removeAll(existingPaymentTypes);
|
||||
// incomingPaymentTypes now only contains the newly added
|
||||
// payment Type mappings
|
||||
for (final Long newPaymentType : incomingPaymentTypes) {
|
||||
final Long newGLAccountId = inputPaymentChannelFundSourceMap.get(newPaymentType);
|
||||
savePaymentChannelToFundSourceMapping(productId, newPaymentType, newGLAccountId, portfolioProductType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param productId
|
||||
*
|
||||
*/
|
||||
private void savePaymentChannelToFundSourceMapping(final Long productId, final Long paymentTypeId,
|
||||
final Long paymentTypeSpecificFundAccountId, final PortfolioProductType portfolioProductType) {
|
||||
final PaymentType paymentType = this.paymentTypeRepositoryWrapper.findOneWithNotFoundDetection(paymentTypeId);
|
||||
final GLAccount glAccount = getAccountById(LoanProductAccountingParams.FUND_SOURCE.getValue(), paymentTypeSpecificFundAccountId);
|
||||
final ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping().setGlAccount(glAccount).setProductId(productId)
|
||||
.setProductType(portfolioProductType.getValue()).setFinancialAccountType(CashAccountsForLoan.FUND_SOURCE.getValue())
|
||||
.setPaymentType(paymentType);
|
||||
this.accountMappingRepository.saveAndFlush(accountMapping);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param productId
|
||||
*
|
||||
*/
|
||||
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;
|
||||
/**
|
||||
* Both CASH and Accrual placeholders have the same value for income from Interest and penalties
|
||||
**/
|
||||
CashAccountsForLoan placeHolderAccountType;
|
||||
if (isPenalty) {
|
||||
glAccount = getAccountByIdAndType(LoanProductAccountingParams.INCOME_ACCOUNT_ID.getValue(), GLAccountType.INCOME,
|
||||
incomeAccountId);
|
||||
placeHolderAccountType = CashAccountsForLoan.INCOME_FROM_PENALTIES;
|
||||
} else {
|
||||
List<GLAccountType> allowedAccountTypes = getAllowedAccountTypesForFeeMapping();
|
||||
glAccount = getAccountByIdAndType(LoanProductAccountingParams.INCOME_ACCOUNT_ID.getValue(), allowedAccountTypes,
|
||||
incomeAccountId);
|
||||
placeHolderAccountType = CashAccountsForLoan.INCOME_FROM_FEES;
|
||||
}
|
||||
final ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping().setGlAccount(glAccount).setProductId(productId)
|
||||
.setProductType(portfolioProductType.getValue()).setFinancialAccountType(placeHolderAccountType.getValue())
|
||||
.setCharge(charge);
|
||||
this.accountMappingRepository.saveAndFlush(accountMapping);
|
||||
}
|
||||
|
||||
private List<GLAccountType> getAllowedAccountTypesForFeeMapping() {
|
||||
List<GLAccountType> allowedAccountTypes = new ArrayList<>();
|
||||
allowedAccountTypes.add(GLAccountType.INCOME);
|
||||
allowedAccountTypes.add(GLAccountType.LIABILITY);
|
||||
return allowedAccountTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches account with a particular Id and throws and Exception it is not of the expected Account Category
|
||||
* ('ASSET','liability' etc)
|
||||
*
|
||||
* @param paramName
|
||||
* @param expectedAccountType
|
||||
* @param accountId
|
||||
* @return
|
||||
*/
|
||||
public GLAccount getAccountByIdAndType(final String paramName, final GLAccountType expectedAccountType, final Long accountId) {
|
||||
final GLAccount glAccount = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountId);
|
||||
|
||||
// validate account is of the expected Type
|
||||
if (glAccount.getType().intValue() != expectedAccountType.getValue()) {
|
||||
throw new ProductToGLAccountMappingInvalidException(paramName, glAccount.getName(), accountId,
|
||||
GLAccountType.fromInt(glAccount.getType()).toString(), expectedAccountType.toString());
|
||||
}
|
||||
return glAccount;
|
||||
}
|
||||
|
||||
public GLAccount getAccountById(final String paramName, final Long accountId) {
|
||||
final GLAccount glAccount = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountId);
|
||||
return glAccount;
|
||||
}
|
||||
|
||||
public GLAccount getAccountByIdAndType(final String paramName, final List<GLAccountType> expectedAccountTypes, final Long accountId) {
|
||||
final GLAccount glAccount = this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountId);
|
||||
// validate account is of the expected Type
|
||||
List<Integer> glAccountTypeValues = new ArrayList<>();
|
||||
for (GLAccountType glAccountType : expectedAccountTypes) {
|
||||
glAccountTypeValues.add(glAccountType.getValue());
|
||||
}
|
||||
if (!glAccountTypeValues.contains(glAccount.getType())) {
|
||||
throw new ProductToGLAccountMappingInvalidException(paramName, glAccount.getName(), accountId,
|
||||
GLAccountType.fromInt(glAccount.getType()).toString(), glAccountTypeValues.toString());
|
||||
}
|
||||
return glAccount;
|
||||
}
|
||||
|
||||
public void deleteProductToGLAccountMapping(final Long loanProductId, final PortfolioProductType portfolioProductType) {
|
||||
final List<ProductToGLAccountMapping> productToGLAccountMappings = this.accountMappingRepository
|
||||
.findByProductIdAndProductType(loanProductId, portfolioProductType.getValue());
|
||||
if (productToGLAccountMappings != null && productToGLAccountMappings.size() > 0) {
|
||||
this.accountMappingRepository.deleteAllInBatch(productToGLAccountMappings);
|
||||
}
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 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.List;
|
||||
import java.util.Map;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
||||
|
||||
public interface ProductToGLAccountMappingReadPlatformService {
|
||||
|
||||
Map<String, Object> fetchAccountMappingDetailsForLoanProduct(Long loanProductId, Integer accountingType);
|
||||
|
||||
List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForLoanProduct(Long loanProductId);
|
||||
|
||||
List<ChargeToGLAccountMapper> fetchFeeToGLAccountMappingsForLoanProduct(Long loanProductId);
|
||||
|
||||
List<ChargeToGLAccountMapper> fetchPenaltyToIncomeAccountMappingsForLoanProduct(Long loanProductId);
|
||||
|
||||
Map<String, Object> fetchAccountMappingDetailsForSavingsProduct(Long savingsProductId, Integer accountingType);
|
||||
|
||||
List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForSavingsProduct(Long savingsProductId);
|
||||
|
||||
List<ChargeToGLAccountMapper> fetchFeeToIncomeAccountMappingsForSavingsProduct(Long savingsProductId);
|
||||
|
||||
List<ChargeToGLAccountMapper> fetchPenaltyToIncomeAccountMappingsForSavingsProduct(Long savingsProductId);
|
||||
|
||||
Map<String, Object> fetchAccountMappingDetailsForShareProduct(Long productId, Integer accountingType);
|
||||
|
||||
List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForShareProduct(Long productId);
|
||||
|
||||
List<ChargeToGLAccountMapper> fetchFeeToIncomeAccountMappingsForShareProduct(Long productId);
|
||||
|
||||
}
|
||||
+415
@@ -0,0 +1,415 @@
|
||||
/**
|
||||
* 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.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.AccrualAccountsForLoan;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForLoan;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForSavings;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForShares;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.LoanProductAccountingDataParams;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.SavingProductAccountingDataParams;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.SharesProductAccountingParams;
|
||||
import org.apache.fineract.accounting.common.AccountingRuleType;
|
||||
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
||||
import org.apache.fineract.portfolio.charge.data.ChargeData;
|
||||
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ProductToGLAccountMappingReadPlatformServiceImpl implements ProductToGLAccountMappingReadPlatformService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
private static final class ProductToGLAccountMappingMapper implements RowMapper<Map<String, Object>> {
|
||||
|
||||
public String schema() {
|
||||
return " mapping.id as id, mapping.gl_account_id as glAccountId,glaccount.name as name,glaccount.gl_code as code,"
|
||||
+ " 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 "
|
||||
+ " from acc_product_mapping mapping left join m_charge charge on mapping.charge_id=charge.id "
|
||||
+ " left join acc_gl_account as glaccount on mapping.gl_account_id = glaccount.id"
|
||||
+ " left join m_payment_type pt on mapping.payment_type=pt.id" + " where mapping.product_type= ? ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long id = rs.getLong("id");
|
||||
final Long glAccountId = rs.getLong("glAccountId");
|
||||
final Long productId = rs.getLong("productId");
|
||||
final Long paymentTypeId = JdbcSupport.getLong(rs, "paymentTypeId");
|
||||
final Long chargeId = rs.getLong("chargeId");
|
||||
final Integer productType = rs.getInt("productType");
|
||||
final String paymentTypeValue = rs.getString("paymentTypeValue");
|
||||
final Integer financialAccountType = rs.getInt("financialAccountType");
|
||||
final String glAccountName = rs.getString("name");
|
||||
final String glCode = rs.getString("code");
|
||||
final String chargeName = rs.getString("chargeName");
|
||||
final Boolean penalty = rs.getBoolean("penalty");
|
||||
|
||||
final Map<String, Object> loanProductToGLAccountMap = new LinkedHashMap<>(5);
|
||||
loanProductToGLAccountMap.put("id", id);
|
||||
loanProductToGLAccountMap.put("glAccountId", glAccountId);
|
||||
loanProductToGLAccountMap.put("productId", productId);
|
||||
loanProductToGLAccountMap.put("productType", productType);
|
||||
loanProductToGLAccountMap.put("financialAccountType", financialAccountType);
|
||||
loanProductToGLAccountMap.put("paymentTypeId", paymentTypeId);
|
||||
loanProductToGLAccountMap.put("paymentTypeValue", paymentTypeValue);
|
||||
loanProductToGLAccountMap.put("chargeId", chargeId);
|
||||
loanProductToGLAccountMap.put("chargeName", chargeName);
|
||||
loanProductToGLAccountMap.put("penalty", penalty);
|
||||
loanProductToGLAccountMap.put("glAccountName", glAccountName);
|
||||
loanProductToGLAccountMap.put("glCode", glCode);
|
||||
return loanProductToGLAccountMap;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> fetchAccountMappingDetailsForLoanProduct(final Long loanProductId, final Integer accountingType) {
|
||||
|
||||
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
||||
|
||||
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
|
||||
final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is null and mapping.charge_id is null";
|
||||
|
||||
final List<Map<String, Object>> listOfProductToGLAccountMaps = this.jdbcTemplate.query(sql, rm, // NOSONAR
|
||||
new Object[] { PortfolioProductType.LOAN.getValue(), loanProductId });
|
||||
|
||||
if (AccountingRuleType.CASH_BASED.getValue().equals(accountingType)) {
|
||||
|
||||
for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {
|
||||
|
||||
final Integer financialAccountType = (Integer) productToGLAccountMap.get("financialAccountType");
|
||||
final CashAccountsForLoan glAccountForLoan = CashAccountsForLoan.fromInt(financialAccountType);
|
||||
|
||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
||||
|
||||
if (glAccountForLoan.equals(CashAccountsForLoan.FUND_SOURCE)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.FUND_SOURCE.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.INCOME_FROM_FEES)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_FEES.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.INCOME_FROM_PENALTIES)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_PENALTIES.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.INTEREST_ON_LOANS)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INTEREST_ON_LOANS.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.LOAN_PORTFOLIO)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.LOAN_PORTFOLIO.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.TRANSFERS_SUSPENSE)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.TRANSFERS_SUSPENSE.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.LOSSES_WRITTEN_OFF)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.LOSSES_WRITTEN_OFF.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.GOODWILL_CREDIT)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.GOODWILL_CREDIT.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.OVERPAYMENT)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.OVERPAYMENT.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.INCOME_FROM_RECOVERY)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_RECOVERY.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_FEES)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_CHARGE_OFF_FEES.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.CHARGE_OFF_EXPENSE)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.CHARGE_OFF_EXPENSE.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.CHARGE_OFF_FRAUD_EXPENSE.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.INCOME_FROM_CHARGE_OFF_PENALTY)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_CHARGE_OFF_PENALTY.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_INTEREST)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_GOODWILL_CREDIT_INTEREST.getValue(),
|
||||
gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_FEES)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_GOODWILL_CREDIT_FEES.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(CashAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(),
|
||||
gLAccountData);
|
||||
}
|
||||
|
||||
}
|
||||
} else if (AccountingRuleType.ACCRUAL_UPFRONT.getValue().equals(accountingType)
|
||||
|| AccountingRuleType.ACCRUAL_PERIODIC.getValue().equals(accountingType)) {
|
||||
|
||||
for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {
|
||||
final Integer financialAccountType = (Integer) productToGLAccountMap.get("financialAccountType");
|
||||
final AccrualAccountsForLoan glAccountForLoan = AccrualAccountsForLoan.fromInt(financialAccountType);
|
||||
|
||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
||||
|
||||
if (glAccountForLoan.equals(AccrualAccountsForLoan.FUND_SOURCE)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.FUND_SOURCE.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_FEES)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_FEES.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_PENALTIES)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_PENALTIES.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INTEREST_ON_LOANS)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INTEREST_ON_LOANS.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.LOAN_PORTFOLIO)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.LOAN_PORTFOLIO.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.OVERPAYMENT)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.OVERPAYMENT.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.TRANSFERS_SUSPENSE)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.TRANSFERS_SUSPENSE.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.LOSSES_WRITTEN_OFF)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.LOSSES_WRITTEN_OFF.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.GOODWILL_CREDIT)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.GOODWILL_CREDIT.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INTEREST_RECEIVABLE)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INTEREST_RECEIVABLE.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.FEES_RECEIVABLE)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.FEES_RECEIVABLE.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.PENALTIES_RECEIVABLE)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.PENALTIES_RECEIVABLE.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_RECOVERY)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_RECOVERY.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_FEES)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_CHARGE_OFF_FEES.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.CHARGE_OFF_EXPENSE)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.CHARGE_OFF_EXPENSE.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.CHARGE_OFF_FRAUD_EXPENSE.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_PENALTY)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_CHARGE_OFF_PENALTY.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_INTEREST)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_GOODWILL_CREDIT_INTEREST.getValue(),
|
||||
gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_FEES)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_GOODWILL_CREDIT_FEES.getValue(), gLAccountData);
|
||||
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY)) {
|
||||
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(),
|
||||
gLAccountData);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return accountMappingDetails;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> fetchAccountMappingDetailsForSavingsProduct(final Long savingsProductId, final Integer accountingType) {
|
||||
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
||||
|
||||
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
|
||||
final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is null and mapping.charge_id is null ";
|
||||
|
||||
final List<Map<String, Object>> listOfProductToGLAccountMaps = this.jdbcTemplate.query(sql, rm, // NOSONAR
|
||||
new Object[] { PortfolioProductType.SAVING.getValue(), savingsProductId });
|
||||
|
||||
if (AccountingRuleType.CASH_BASED.getValue().equals(accountingType)) {
|
||||
|
||||
for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {
|
||||
|
||||
final Integer financialAccountType = (Integer) productToGLAccountMap.get("financialAccountType");
|
||||
final CashAccountsForSavings glAccountForSavings = CashAccountsForSavings.fromInt(financialAccountType);
|
||||
|
||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
||||
|
||||
if (glAccountForSavings.equals(CashAccountsForSavings.SAVINGS_REFERENCE)) {
|
||||
accountMappingDetails.put(SavingProductAccountingDataParams.SAVINGS_REFERENCE.getValue(), gLAccountData);
|
||||
} else if (glAccountForSavings.equals(CashAccountsForSavings.SAVINGS_CONTROL)) {
|
||||
accountMappingDetails.put(SavingProductAccountingDataParams.SAVINGS_CONTROL.getValue(), gLAccountData);
|
||||
} else if (glAccountForSavings.equals(CashAccountsForSavings.INCOME_FROM_FEES)) {
|
||||
accountMappingDetails.put(SavingProductAccountingDataParams.INCOME_FROM_FEES.getValue(), gLAccountData);
|
||||
} else if (glAccountForSavings.equals(CashAccountsForSavings.INCOME_FROM_PENALTIES)) {
|
||||
accountMappingDetails.put(SavingProductAccountingDataParams.INCOME_FROM_PENALTIES.getValue(), gLAccountData);
|
||||
} else if (glAccountForSavings.equals(CashAccountsForSavings.TRANSFERS_SUSPENSE)) {
|
||||
accountMappingDetails.put(SavingProductAccountingDataParams.TRANSFERS_SUSPENSE.getValue(), gLAccountData);
|
||||
} else if (glAccountForSavings.equals(CashAccountsForSavings.INTEREST_ON_SAVINGS)) {
|
||||
accountMappingDetails.put(SavingProductAccountingDataParams.INTEREST_ON_SAVINGS.getValue(), gLAccountData);
|
||||
} else if (glAccountForSavings.equals(CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL)) {
|
||||
accountMappingDetails.put(SavingProductAccountingDataParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), gLAccountData);
|
||||
} else if (glAccountForSavings.equals(CashAccountsForSavings.LOSSES_WRITTEN_OFF)) {
|
||||
accountMappingDetails.put(SavingProductAccountingDataParams.LOSSES_WRITTEN_OFF.getValue(), gLAccountData);
|
||||
} else if (glAccountForSavings.equals(CashAccountsForSavings.INCOME_FROM_INTEREST)) {
|
||||
accountMappingDetails.put(SavingProductAccountingDataParams.INCOME_FROM_INTEREST.getValue(), gLAccountData);
|
||||
} else if (glAccountForSavings.equals(CashAccountsForSavings.ESCHEAT_LIABILITY)) {
|
||||
accountMappingDetails.put(SavingProductAccountingDataParams.ESCHEAT_LIABILITY.getValue(), gLAccountData);
|
||||
}
|
||||
}
|
||||
}
|
||||
return accountMappingDetails;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForLoanProduct(final Long loanProductId) {
|
||||
return fetchPaymentTypeToFundSourceMappings(PortfolioProductType.LOAN, loanProductId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForSavingsProduct(final Long savingsProductId) {
|
||||
return fetchPaymentTypeToFundSourceMappings(PortfolioProductType.SAVING, savingsProductId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param loanProductId
|
||||
* @return
|
||||
*/
|
||||
private List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappings(final PortfolioProductType portfolioProductType,
|
||||
final Long loanProductId) {
|
||||
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
|
||||
final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is not null";
|
||||
|
||||
final List<Map<String, Object>> paymentTypeToFundSourceMappingsList = this.jdbcTemplate.query(sql, rm, // NOSONAR
|
||||
new Object[] { portfolioProductType.getValue(), loanProductId });
|
||||
|
||||
List<PaymentTypeToGLAccountMapper> paymentTypeToGLAccountMappers = null;
|
||||
for (final Map<String, Object> productToGLAccountMap : paymentTypeToFundSourceMappingsList) {
|
||||
if (paymentTypeToGLAccountMappers == null) {
|
||||
paymentTypeToGLAccountMappers = new ArrayList<>();
|
||||
}
|
||||
final Long paymentTypeId = (Long) productToGLAccountMap.get("paymentTypeId");
|
||||
final String paymentTypeValue = (String) productToGLAccountMap.get("paymentTypeValue");
|
||||
final PaymentTypeData paymentTypeData = PaymentTypeData.instance(paymentTypeId, paymentTypeValue);
|
||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
||||
|
||||
final GLAccountData gLAccountData = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
||||
|
||||
final PaymentTypeToGLAccountMapper paymentTypeToGLAccountMapper = new PaymentTypeToGLAccountMapper()
|
||||
.setPaymentType(paymentTypeData).setFundSourceAccount(gLAccountData);
|
||||
paymentTypeToGLAccountMappers.add(paymentTypeToGLAccountMapper);
|
||||
}
|
||||
return paymentTypeToGLAccountMappers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChargeToGLAccountMapper> fetchFeeToGLAccountMappingsForLoanProduct(final Long loanProductId) {
|
||||
return fetchChargeToIncomeAccountMappings(PortfolioProductType.LOAN, loanProductId, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChargeToGLAccountMapper> fetchPenaltyToIncomeAccountMappingsForLoanProduct(final Long loanProductId) {
|
||||
return fetchChargeToIncomeAccountMappings(PortfolioProductType.LOAN, loanProductId, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChargeToGLAccountMapper> fetchFeeToIncomeAccountMappingsForSavingsProduct(Long savingsProductId) {
|
||||
return fetchChargeToIncomeAccountMappings(PortfolioProductType.SAVING, savingsProductId, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChargeToGLAccountMapper> fetchPenaltyToIncomeAccountMappingsForSavingsProduct(Long savingsProductId) {
|
||||
return fetchChargeToIncomeAccountMappings(PortfolioProductType.SAVING, savingsProductId, true);
|
||||
}
|
||||
|
||||
private List<ChargeToGLAccountMapper> fetchChargeToIncomeAccountMappings(final PortfolioProductType portfolioProductType,
|
||||
final Long loanProductId, final boolean penalty) {
|
||||
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
|
||||
String sql = "select " + rm.schema() + " and product_id = ? and mapping.charge_id is not null and charge.is_penalty=";
|
||||
if (penalty) {
|
||||
sql = sql + " true";
|
||||
} else {
|
||||
sql = sql + " false";
|
||||
}
|
||||
|
||||
final List<Map<String, Object>> chargeToFundSourceMappingsList = this.jdbcTemplate.query(sql, rm, // NOSONAR
|
||||
new Object[] { portfolioProductType.getValue(), loanProductId });
|
||||
List<ChargeToGLAccountMapper> chargeToGLAccountMappers = null;
|
||||
for (final Map<String, Object> chargeToIncomeAccountMap : chargeToFundSourceMappingsList) {
|
||||
if (chargeToGLAccountMappers == null) {
|
||||
chargeToGLAccountMappers = new ArrayList<>();
|
||||
}
|
||||
final Long glAccountId = (Long) chargeToIncomeAccountMap.get("glAccountId");
|
||||
final String glAccountName = (String) chargeToIncomeAccountMap.get("glAccountName");
|
||||
final String glCode = (String) chargeToIncomeAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
||||
final Long chargeId = (Long) chargeToIncomeAccountMap.get("chargeId");
|
||||
final String chargeName = (String) chargeToIncomeAccountMap.get("chargeName");
|
||||
final Boolean penalty1 = (Boolean) chargeToIncomeAccountMap.get("penalty");
|
||||
final ChargeData chargeData = ChargeData.lookup(chargeId, chargeName, penalty1);
|
||||
final ChargeToGLAccountMapper chargeToGLAccountMapper = new ChargeToGLAccountMapper().setCharge(chargeData)
|
||||
.setIncomeAccount(gLAccountData);
|
||||
chargeToGLAccountMappers.add(chargeToGLAccountMapper);
|
||||
}
|
||||
return chargeToGLAccountMappers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> fetchAccountMappingDetailsForShareProduct(Long productId, Integer accountingType) {
|
||||
|
||||
final Map<String, Object> accountMappingDetails = new LinkedHashMap<>(8);
|
||||
|
||||
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
|
||||
final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is null and mapping.charge_id is null ";
|
||||
|
||||
final List<Map<String, Object>> listOfProductToGLAccountMaps = this.jdbcTemplate.query(sql, rm, // NOSONAR
|
||||
new Object[] { PortfolioProductType.SHARES.getValue(), productId });
|
||||
|
||||
if (AccountingRuleType.CASH_BASED.getValue().equals(accountingType)) {
|
||||
for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {
|
||||
final Integer financialAccountType = (Integer) productToGLAccountMap.get("financialAccountType");
|
||||
final CashAccountsForShares glAccountForShares = CashAccountsForShares.fromInt(financialAccountType);
|
||||
|
||||
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
||||
final String glAccountName = (String) productToGLAccountMap.get("glAccountName");
|
||||
final String glCode = (String) productToGLAccountMap.get("glCode");
|
||||
final GLAccountData gLAccountData = new GLAccountData().setId(glAccountId).setName(glAccountName).setGlCode(glCode);
|
||||
|
||||
if (glAccountForShares.equals(CashAccountsForShares.SHARES_REFERENCE)) {
|
||||
accountMappingDetails.put(SharesProductAccountingParams.SHARES_REFERENCE.getValue(), gLAccountData);
|
||||
} else if (glAccountForShares.equals(CashAccountsForShares.SHARES_SUSPENSE)) {
|
||||
accountMappingDetails.put(SharesProductAccountingParams.SHARES_SUSPENSE.getValue(), gLAccountData);
|
||||
} else if (glAccountForShares.equals(CashAccountsForShares.INCOME_FROM_FEES)) {
|
||||
accountMappingDetails.put(SharesProductAccountingParams.INCOME_FROM_FEES.getValue(), gLAccountData);
|
||||
} else if (glAccountForShares.equals(CashAccountsForShares.SHARES_EQUITY)) {
|
||||
accountMappingDetails.put(SharesProductAccountingParams.SHARES_EQUITY.getValue(), gLAccountData);
|
||||
}
|
||||
}
|
||||
}
|
||||
return accountMappingDetails;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForShareProduct(Long productId) {
|
||||
return fetchPaymentTypeToFundSourceMappings(PortfolioProductType.SHARES, productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChargeToGLAccountMapper> fetchFeeToIncomeAccountMappingsForShareProduct(Long productId) {
|
||||
return fetchChargeToIncomeAccountMappings(PortfolioProductType.SHARES, productId, false);
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 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.Map;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.portfolio.savings.DepositAccountType;
|
||||
|
||||
public interface ProductToGLAccountMappingWritePlatformService {
|
||||
|
||||
void createLoanProductToGLAccountMapping(Long loanProductId, JsonCommand command);
|
||||
|
||||
void createSavingProductToGLAccountMapping(Long savingProductId, JsonCommand command, DepositAccountType accountType);
|
||||
|
||||
Map<String, Object> updateLoanProductToGLAccountMapping(Long loanProductId, JsonCommand command, boolean accountingRuleChanged,
|
||||
int accountingRuleTypeId);
|
||||
|
||||
Map<String, Object> updateSavingsProductToGLAccountMapping(Long savingsProductId, JsonCommand command, boolean accountingRuleChanged,
|
||||
int accountingRuleTypeId, DepositAccountType accountType);
|
||||
|
||||
void createShareProductToGLAccountMapping(Long shareProductId, JsonCommand command);
|
||||
|
||||
Map<String, Object> updateShareProductToGLAccountMapping(Long shareProductId, JsonCommand command, boolean accountingRuleChanged,
|
||||
int accountingRuleTypeId);
|
||||
|
||||
}
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
/**
|
||||
* 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 com.google.gson.JsonElement;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForSavings;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.SavingProductAccountingParams;
|
||||
import org.apache.fineract.accounting.common.AccountingRuleType;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepository;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepositoryWrapper;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.paymenttype.domain.PaymentTypeRepositoryWrapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SavingsProductToGLAccountMappingHelper extends ProductToGLAccountMappingHelper {
|
||||
|
||||
public SavingsProductToGLAccountMappingHelper(final GLAccountRepository glAccountRepository,
|
||||
final ProductToGLAccountMappingRepository glAccountMappingRepository, final FromJsonHelper fromApiJsonHelper,
|
||||
final ChargeRepositoryWrapper chargeRepositoryWrapper, final GLAccountRepositoryWrapper accountRepositoryWrapper,
|
||||
final PaymentTypeRepositoryWrapper paymentTypeRepositoryWrapper) {
|
||||
super(glAccountRepository, glAccountMappingRepository, fromApiJsonHelper, chargeRepositoryWrapper, accountRepositoryWrapper,
|
||||
paymentTypeRepositoryWrapper);
|
||||
}
|
||||
|
||||
/***
|
||||
* 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);
|
||||
}
|
||||
|
||||
public void saveSavingsToIncomeAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||
final int placeHolderTypeId) {
|
||||
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.INCOME, PortfolioProductType.SAVING);
|
||||
}
|
||||
|
||||
public void saveSavingsToExpenseAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||
final int placeHolderTypeId) {
|
||||
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.EXPENSE, PortfolioProductType.SAVING);
|
||||
}
|
||||
|
||||
public void saveSavingsToLiabilityAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||
final int placeHolderTypeId) {
|
||||
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.LIABILITY, PortfolioProductType.SAVING);
|
||||
}
|
||||
|
||||
/***
|
||||
* Set of abstractions for merging Savings Products to GL Account Mappings
|
||||
***/
|
||||
|
||||
public void mergeSavingsToAssetAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.ASSET,
|
||||
PortfolioProductType.SAVING);
|
||||
}
|
||||
|
||||
public void mergeSavingsToIncomeAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.INCOME,
|
||||
PortfolioProductType.SAVING);
|
||||
}
|
||||
|
||||
public void mergeSavingsToExpenseAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.EXPENSE,
|
||||
PortfolioProductType.SAVING);
|
||||
}
|
||||
|
||||
public void mergeSavingsToLiabilityAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.LIABILITY,
|
||||
PortfolioProductType.SAVING);
|
||||
}
|
||||
|
||||
public void createOrmergeSavingsToLiabilityAccountMappingChanges(final JsonElement element, final String paramName,
|
||||
final Long productId, final int accountTypeId, final Map<String, Object> changes) {
|
||||
createOrmergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, changes, GLAccountType.LIABILITY,
|
||||
PortfolioProductType.SAVING);
|
||||
}
|
||||
|
||||
/*** Abstractions for payments channel related to savings products ***/
|
||||
|
||||
public void savePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||
final Map<String, Object> changes) {
|
||||
savePaymentChannelToFundSourceMappings(command, element, productId, changes, PortfolioProductType.SAVING);
|
||||
}
|
||||
|
||||
public void updatePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||
final Map<String, Object> changes) {
|
||||
updatePaymentChannelToFundSourceMappings(command, element, productId, changes, PortfolioProductType.SAVING);
|
||||
}
|
||||
|
||||
public void saveChargesToIncomeAccountMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||
final Map<String, Object> changes) {
|
||||
// save both fee and penalty charges
|
||||
saveChargesToGLAccountMappings(command, element, productId, changes, PortfolioProductType.SAVING, true);
|
||||
saveChargesToGLAccountMappings(command, element, productId, changes, PortfolioProductType.SAVING, false);
|
||||
}
|
||||
|
||||
public void updateChargesToIncomeAccountMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||
final Map<String, Object> changes) {
|
||||
// update both fee and penalty charges
|
||||
updateChargeToIncomeAccountMappings(command, element, productId, changes, PortfolioProductType.SAVING, true);
|
||||
updateChargeToIncomeAccountMappings(command, element, productId, changes, PortfolioProductType.SAVING, false);
|
||||
}
|
||||
|
||||
public Map<String, Object> populateChangesForNewSavingsProductToGLAccountMappingCreation(final JsonElement element,
|
||||
final AccountingRuleType accountingRuleType) {
|
||||
final Map<String, Object> changes = new HashMap<>();
|
||||
|
||||
final Long savingsReferenceId = this.fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(),
|
||||
element);
|
||||
final Long incomeFromFeesId = this.fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_FEES.getValue(),
|
||||
element);
|
||||
final Long incomeFromPenaltiesId = this.fromApiJsonHelper
|
||||
.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(), element);
|
||||
final Long interestOnSavingsId = this.fromApiJsonHelper
|
||||
.extractLongNamed(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(), element);
|
||||
final Long savingsControlId = this.fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.SAVINGS_CONTROL.getValue(),
|
||||
element);
|
||||
final Long transfersInSuspenseAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(), element);
|
||||
final Long overdraftControlId = this.fromApiJsonHelper
|
||||
.extractLongNamed(SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), element);
|
||||
final Long incomeFromInterest = this.fromApiJsonHelper
|
||||
.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue(), element);
|
||||
final Long writeOffId = this.fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(),
|
||||
element);
|
||||
switch (accountingRuleType) {
|
||||
case NONE:
|
||||
break;
|
||||
case CASH_BASED:
|
||||
changes.put(SavingProductAccountingParams.SAVINGS_CONTROL.getValue(), savingsControlId);
|
||||
changes.put(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(), savingsReferenceId);
|
||||
changes.put(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(), interestOnSavingsId);
|
||||
changes.put(SavingProductAccountingParams.INCOME_FROM_FEES.getValue(), incomeFromFeesId);
|
||||
changes.put(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(), incomeFromPenaltiesId);
|
||||
changes.put(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(), transfersInSuspenseAccountId);
|
||||
changes.put(SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), overdraftControlId);
|
||||
changes.put(SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue(), incomeFromInterest);
|
||||
changes.put(SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(), writeOffId);
|
||||
break;
|
||||
case ACCRUAL_PERIODIC:
|
||||
break;
|
||||
case ACCRUAL_UPFRONT:
|
||||
break;
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Examines and updates each account mapping for given loan product with changes passed in from the Json element
|
||||
*
|
||||
* @param savingsProductId
|
||||
* @param changes
|
||||
* @param element
|
||||
* @param accountingRuleType
|
||||
*/
|
||||
public void handleChangesToSavingsProductToGLAccountMappings(final Long savingsProductId, final Map<String, Object> changes,
|
||||
final JsonElement element, final AccountingRuleType accountingRuleType) {
|
||||
switch (accountingRuleType) {
|
||||
case NONE:
|
||||
break;
|
||||
case CASH_BASED:
|
||||
// asset
|
||||
mergeSavingsToAssetAccountMappingChanges(element, SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(),
|
||||
savingsProductId, CashAccountsForSavings.SAVINGS_REFERENCE.getValue(),
|
||||
CashAccountsForSavings.SAVINGS_REFERENCE.toString(), changes);
|
||||
|
||||
mergeSavingsToAssetAccountMappingChanges(element, SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
|
||||
savingsProductId, CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
|
||||
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.toString(), changes);
|
||||
|
||||
// income
|
||||
mergeSavingsToIncomeAccountMappingChanges(element, SavingProductAccountingParams.INCOME_FROM_FEES.getValue(),
|
||||
savingsProductId, CashAccountsForSavings.INCOME_FROM_FEES.getValue(),
|
||||
CashAccountsForSavings.INCOME_FROM_FEES.toString(), changes);
|
||||
|
||||
mergeSavingsToIncomeAccountMappingChanges(element, SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(),
|
||||
savingsProductId, CashAccountsForSavings.INCOME_FROM_PENALTIES.getValue(),
|
||||
CashAccountsForSavings.INCOME_FROM_PENALTIES.toString(), changes);
|
||||
|
||||
mergeSavingsToIncomeAccountMappingChanges(element, SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue(),
|
||||
savingsProductId, CashAccountsForSavings.INCOME_FROM_INTEREST.getValue(),
|
||||
CashAccountsForSavings.INCOME_FROM_INTEREST.toString(), changes);
|
||||
|
||||
// expenses
|
||||
mergeSavingsToExpenseAccountMappingChanges(element, SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(),
|
||||
savingsProductId, CashAccountsForSavings.INTEREST_ON_SAVINGS.getValue(),
|
||||
CashAccountsForSavings.INTEREST_ON_SAVINGS.toString(), changes);
|
||||
mergeSavingsToExpenseAccountMappingChanges(element, SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(),
|
||||
savingsProductId, CashAccountsForSavings.LOSSES_WRITTEN_OFF.getValue(),
|
||||
CashAccountsForSavings.LOSSES_WRITTEN_OFF.toString(), changes);
|
||||
|
||||
// liability
|
||||
mergeSavingsToLiabilityAccountMappingChanges(element, SavingProductAccountingParams.SAVINGS_CONTROL.getValue(),
|
||||
savingsProductId, CashAccountsForSavings.SAVINGS_CONTROL.getValue(),
|
||||
CashAccountsForSavings.SAVINGS_CONTROL.toString(), changes);
|
||||
mergeSavingsToLiabilityAccountMappingChanges(element, SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(),
|
||||
savingsProductId, CashAccountsForSavings.TRANSFERS_SUSPENSE.getValue(),
|
||||
CashAccountsForSavings.TRANSFERS_SUSPENSE.toString(), changes);
|
||||
createOrmergeSavingsToLiabilityAccountMappingChanges(element, SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue(),
|
||||
savingsProductId, CashAccountsForSavings.ESCHEAT_LIABILITY.getValue(), changes);
|
||||
break;
|
||||
case ACCRUAL_PERIODIC:
|
||||
break;
|
||||
case ACCRUAL_UPFRONT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteSavingsProductToGLAccountMapping(final Long savingsProductId) {
|
||||
deleteProductToGLAccountMapping(savingsProductId, PortfolioProductType.SAVING);
|
||||
}
|
||||
}
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* 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 com.google.gson.JsonElement;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForShares;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.SharesProductAccountingParams;
|
||||
import org.apache.fineract.accounting.common.AccountingRuleType;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepository;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepositoryWrapper;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.paymenttype.domain.PaymentTypeRepositoryWrapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ShareProductToGLAccountMappingHelper extends ProductToGLAccountMappingHelper {
|
||||
|
||||
public ShareProductToGLAccountMappingHelper(final GLAccountRepository glAccountRepository,
|
||||
final ProductToGLAccountMappingRepository glAccountMappingRepository, final FromJsonHelper fromApiJsonHelper,
|
||||
final ChargeRepositoryWrapper chargeRepositoryWrapper, final GLAccountRepositoryWrapper accountRepositoryWrapper,
|
||||
final PaymentTypeRepositoryWrapper paymentTypeRepositoryWrapper) {
|
||||
super(glAccountRepository, glAccountMappingRepository, fromApiJsonHelper, chargeRepositoryWrapper, accountRepositoryWrapper,
|
||||
paymentTypeRepositoryWrapper);
|
||||
}
|
||||
|
||||
/***
|
||||
* Set of abstractions for saving Share Products to GL Account Mappings
|
||||
***/
|
||||
|
||||
public void saveSharesToAssetAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||
final int placeHolderTypeId) {
|
||||
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.ASSET, PortfolioProductType.SHARES);
|
||||
}
|
||||
|
||||
public void saveSharesToIncomeAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||
final int placeHolderTypeId) {
|
||||
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.INCOME, PortfolioProductType.SHARES);
|
||||
}
|
||||
|
||||
public void saveSharesToEquityAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||
final int placeHolderTypeId) {
|
||||
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.EQUITY, PortfolioProductType.SHARES);
|
||||
}
|
||||
|
||||
public void saveSharesToLiabilityAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||
final int placeHolderTypeId) {
|
||||
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.LIABILITY, PortfolioProductType.SHARES);
|
||||
}
|
||||
|
||||
/***
|
||||
* Set of abstractions for merging Shares Products to GL Account Mappings
|
||||
***/
|
||||
|
||||
public void mergeSharesToAssetAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.ASSET,
|
||||
PortfolioProductType.SHARES);
|
||||
}
|
||||
|
||||
public void mergeSharesToIncomeAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.INCOME,
|
||||
PortfolioProductType.SHARES);
|
||||
}
|
||||
|
||||
public void mergeSharesToEquityAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.EQUITY,
|
||||
PortfolioProductType.SHARES);
|
||||
}
|
||||
|
||||
public void mergeSharesToLiabilityAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.LIABILITY,
|
||||
PortfolioProductType.SHARES);
|
||||
}
|
||||
|
||||
/*** Abstractions for payments channel related to Shares products ***/
|
||||
|
||||
public void savePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||
final Map<String, Object> changes) {
|
||||
savePaymentChannelToFundSourceMappings(command, element, productId, changes, PortfolioProductType.SHARES);
|
||||
}
|
||||
|
||||
public void updatePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||
final Map<String, Object> changes) {
|
||||
updatePaymentChannelToFundSourceMappings(command, element, productId, changes, PortfolioProductType.SHARES);
|
||||
}
|
||||
|
||||
public void saveChargesToIncomeAccountMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||
final Map<String, Object> changes) {
|
||||
saveChargesToGLAccountMappings(command, element, productId, changes, PortfolioProductType.SHARES, true);
|
||||
saveChargesToGLAccountMappings(command, element, productId, changes, PortfolioProductType.SHARES, false);
|
||||
}
|
||||
|
||||
public void updateChargesToIncomeAccountMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||
final Map<String, Object> changes) {
|
||||
updateChargeToIncomeAccountMappings(command, element, productId, changes, PortfolioProductType.SHARES, true);
|
||||
updateChargeToIncomeAccountMappings(command, element, productId, changes, PortfolioProductType.SHARES, false);
|
||||
}
|
||||
|
||||
public Map<String, Object> populateChangesForNewSharesProductToGLAccountMappingCreation(final JsonElement element,
|
||||
final AccountingRuleType accountingRuleType) {
|
||||
final Map<String, Object> changes = new HashMap<>();
|
||||
|
||||
final Long shareReferenceId = this.fromApiJsonHelper.extractLongNamed(SharesProductAccountingParams.SHARES_REFERENCE.getValue(),
|
||||
element);
|
||||
final Long incomeFromFeeAccountId = this.fromApiJsonHelper
|
||||
.extractLongNamed(SharesProductAccountingParams.INCOME_FROM_FEES.getValue(), element);
|
||||
final Long shareSuspenseId = this.fromApiJsonHelper.extractLongNamed(SharesProductAccountingParams.SHARES_SUSPENSE.getValue(),
|
||||
element);
|
||||
final Long shareEquityId = this.fromApiJsonHelper.extractLongNamed(SharesProductAccountingParams.SHARES_EQUITY.getValue(), element);
|
||||
|
||||
switch (accountingRuleType) {
|
||||
case NONE:
|
||||
break;
|
||||
case CASH_BASED:
|
||||
changes.put(SharesProductAccountingParams.SHARES_REFERENCE.getValue(), shareReferenceId);
|
||||
changes.put(SharesProductAccountingParams.INCOME_FROM_FEES.getValue(), incomeFromFeeAccountId);
|
||||
changes.put(SharesProductAccountingParams.SHARES_SUSPENSE.getValue(), shareSuspenseId);
|
||||
changes.put(SharesProductAccountingParams.SHARES_EQUITY.getValue(), shareEquityId);
|
||||
break;
|
||||
case ACCRUAL_PERIODIC:
|
||||
break;
|
||||
case ACCRUAL_UPFRONT:
|
||||
break;
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Examines and updates each account mapping for given loan product with changes passed in from the Json element
|
||||
*
|
||||
* @param sharesProductId
|
||||
* @param changes
|
||||
* @param element
|
||||
* @param accountingRuleType
|
||||
*/
|
||||
public void handleChangesToSharesProductToGLAccountMappings(final Long sharesProductId, final Map<String, Object> changes,
|
||||
final JsonElement element, final AccountingRuleType accountingRuleType) {
|
||||
switch (accountingRuleType) {
|
||||
case NONE:
|
||||
break;
|
||||
case CASH_BASED:
|
||||
// asset
|
||||
mergeSharesToAssetAccountMappingChanges(element, SharesProductAccountingParams.SHARES_REFERENCE.getValue(), sharesProductId,
|
||||
CashAccountsForShares.SHARES_REFERENCE.getValue(), CashAccountsForShares.SHARES_REFERENCE.toString(), changes);
|
||||
|
||||
// income
|
||||
mergeSharesToIncomeAccountMappingChanges(element, SharesProductAccountingParams.INCOME_FROM_FEES.getValue(),
|
||||
sharesProductId, CashAccountsForShares.INCOME_FROM_FEES.getValue(),
|
||||
CashAccountsForShares.INCOME_FROM_FEES.toString(), changes);
|
||||
|
||||
// liability
|
||||
mergeSharesToLiabilityAccountMappingChanges(element, SharesProductAccountingParams.SHARES_SUSPENSE.getValue(),
|
||||
sharesProductId, CashAccountsForShares.SHARES_SUSPENSE.getValue(), CashAccountsForShares.SHARES_SUSPENSE.toString(),
|
||||
changes);
|
||||
|
||||
// equity
|
||||
mergeSharesToEquityAccountMappingChanges(element, SharesProductAccountingParams.SHARES_EQUITY.getValue(), sharesProductId,
|
||||
CashAccountsForShares.SHARES_EQUITY.getValue(), CashAccountsForShares.SHARES_EQUITY.toString(), changes);
|
||||
break;
|
||||
case ACCRUAL_PERIODIC:
|
||||
break;
|
||||
case ACCRUAL_UPFRONT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteSharesProductToGLAccountMapping(final Long sharesProductId) {
|
||||
deleteProductToGLAccountMapping(sharesProductId, PortfolioProductType.SHARES);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user