accounting posting wip (only loan product mapping)
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
ALTER TABLE `m_product_loan`
|
||||
ADD COLUMN `accounting_type` SMALLINT(5) NOT NULL AFTER `amortization_method_enum`;
|
||||
|
||||
update m_product_loan set accounting_type=1;
|
||||
|
||||
DROP TABLE if exists `acc_product_mapping`;
|
||||
|
||||
CREATE TABLE `acc_product_mapping` (
|
||||
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
`gl_account_id` BIGINT(20) NULL DEFAULT NULL,
|
||||
`product_id` BIGINT(20) NULL DEFAULT NULL,
|
||||
`product_type` SMALLINT(5) NULL DEFAULT NULL,
|
||||
`financial_account_type` SMALLINT(5) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
)
|
||||
COLLATE='utf8_general_ci'
|
||||
ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package org.mifosplatform.accounting;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class AccountingConstants {
|
||||
|
||||
/*** Categories for Accounting **/
|
||||
@@ -32,4 +35,128 @@ public class AccountingConstants {
|
||||
}
|
||||
}
|
||||
|
||||
/*** Types of portfolio products ***/
|
||||
public static enum PORTFOLIO_PRODUCT_TYPE {
|
||||
LOAN(1), SAVING(2);
|
||||
|
||||
private final Integer value;
|
||||
|
||||
private PORTFOLIO_PRODUCT_TYPE(final Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
private static final Map<Integer, PORTFOLIO_PRODUCT_TYPE> intToEnumMap = new HashMap<Integer, PORTFOLIO_PRODUCT_TYPE>();
|
||||
static {
|
||||
for (PORTFOLIO_PRODUCT_TYPE type : PORTFOLIO_PRODUCT_TYPE.values()) {
|
||||
intToEnumMap.put(type.value, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static PORTFOLIO_PRODUCT_TYPE fromInt(int i) {
|
||||
PORTFOLIO_PRODUCT_TYPE type = intToEnumMap.get(Integer.valueOf(i));
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
/*** Accounting placeholders for cash based accounting for loan products ***/
|
||||
public static enum CASH_ACCOUNTS_FOR_LOAN {
|
||||
FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), LOSSES_WRITTEN_OFF(6);
|
||||
|
||||
private final Integer value;
|
||||
|
||||
private CASH_ACCOUNTS_FOR_LOAN(final Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
private static final Map<Integer, CASH_ACCOUNTS_FOR_LOAN> intToEnumMap = new HashMap<Integer, CASH_ACCOUNTS_FOR_LOAN>();
|
||||
static {
|
||||
for (CASH_ACCOUNTS_FOR_LOAN type : CASH_ACCOUNTS_FOR_LOAN.values()) {
|
||||
intToEnumMap.put(type.value, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static CASH_ACCOUNTS_FOR_LOAN fromInt(int i) {
|
||||
CASH_ACCOUNTS_FOR_LOAN type = intToEnumMap.get(Integer.valueOf(i));
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
/*** Accounting placeholders for accrual based accounting for loan products ***/
|
||||
public static enum ACCRUAL_ACCOUNTS_FOR_LOAN {
|
||||
FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), LOSSES_WRITTEN_OFF(6), INTEREST_RECEIVABLE(
|
||||
7), FEES_RECEIVABLE(8), PENALTIES_RECEIVABLE(9);
|
||||
|
||||
private final Integer value;
|
||||
|
||||
private ACCRUAL_ACCOUNTS_FOR_LOAN(final Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
private static final Map<Integer, ACCRUAL_ACCOUNTS_FOR_LOAN> intToEnumMap = new HashMap<Integer, ACCRUAL_ACCOUNTS_FOR_LOAN>();
|
||||
static {
|
||||
for (ACCRUAL_ACCOUNTS_FOR_LOAN type : ACCRUAL_ACCOUNTS_FOR_LOAN.values()) {
|
||||
intToEnumMap.put(type.value, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static ACCRUAL_ACCOUNTS_FOR_LOAN fromInt(int i) {
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN type = intToEnumMap.get(Integer.valueOf(i));
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/***
|
||||
* Enum of all accounting related input parameter names used while
|
||||
* creating/updating a loan product
|
||||
***/
|
||||
public static enum LOAN_PRODUCT_ACCOUNTING_PARAMS {
|
||||
FUND_SOURCE("fundSourceAccountId"), LOAN_PORTFOLIO("loanPortfolioAccountId"), INTEREST_ON_LOANS("interestOnLoanAccountId"), INCOME_FROM_FEES(
|
||||
"incomeFromFeeAccountId"), INCOME_FROM_PENALTIES("incomeFromPenaltyAccountId"), LOSSES_WRITTEN_OFF("writeOffAccountId"), INTEREST_RECEIVABLE(
|
||||
"receivableInterestAccountId"), FEES_RECEIVABLE("receivableFeeAccountId"), PENALTIES_RECEIVABLE(
|
||||
"receivablePenaltyAccountId");
|
||||
|
||||
private final String value;
|
||||
|
||||
private LOAN_PRODUCT_ACCOUNTING_PARAMS(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package org.mifosplatform.accounting.api.commands;
|
||||
|
||||
|
||||
public class ProductToGLAccountMappingCommand {
|
||||
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package org.mifosplatform.accounting.api.data;
|
||||
|
||||
public class ProductToGLAccountMappingData {
|
||||
|
||||
private final Long id;
|
||||
private final Long glAccountId;
|
||||
private final Long productId;
|
||||
private final Integer productType;
|
||||
private final Integer financialAccountType;
|
||||
|
||||
public ProductToGLAccountMappingData(Long id, Long glAccountId, Long productId, Integer productType, Integer financialAccountType) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.glAccountId = glAccountId;
|
||||
this.productId = productId;
|
||||
this.productType = productType;
|
||||
this.financialAccountType = financialAccountType;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public Long getGlAccountId() {
|
||||
return this.glAccountId;
|
||||
}
|
||||
|
||||
public Long getProductId() {
|
||||
return this.productId;
|
||||
}
|
||||
|
||||
public Integer getProductType() {
|
||||
return this.productType;
|
||||
}
|
||||
|
||||
public Integer getFinancialAccountType() {
|
||||
return this.financialAccountType;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+79
@@ -0,0 +1,79 @@
|
||||
package org.mifosplatform.accounting.domain;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "acc_product_mapping", uniqueConstraints = { @UniqueConstraint(columnNames = { "product_id", "product_type",
|
||||
"financial_account_type" }, name = "financial_action") })
|
||||
public class ProductToGLAccountMapping extends AbstractPersistable<Long> {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "gl_account_id")
|
||||
private GLAccount glAccount;
|
||||
|
||||
@Column(name = "product_id", nullable = false)
|
||||
private Long productId;
|
||||
|
||||
@Column(name = "product_type", nullable = false)
|
||||
private int productType;
|
||||
|
||||
@Column(name = "financial_account_type", nullable = false)
|
||||
private int financialAccountType;
|
||||
|
||||
public static ProductToGLAccountMapping createNew(final GLAccount glAccount, final Long productId, final int productType,
|
||||
final int financialAccountType) {
|
||||
return new ProductToGLAccountMapping(glAccount, productId, productType, financialAccountType);
|
||||
}
|
||||
|
||||
protected ProductToGLAccountMapping() {
|
||||
//
|
||||
}
|
||||
|
||||
public ProductToGLAccountMapping(GLAccount glAccount, Long productId, int productType, int financialAccountType) {
|
||||
this.glAccount = glAccount;
|
||||
this.productId = productId;
|
||||
this.productType = productType;
|
||||
this.financialAccountType = financialAccountType;
|
||||
}
|
||||
|
||||
public GLAccount getGlAccount() {
|
||||
return this.glAccount;
|
||||
}
|
||||
|
||||
public void setGlAccount(GLAccount glAccount) {
|
||||
this.glAccount = glAccount;
|
||||
}
|
||||
|
||||
public Long getProductId() {
|
||||
return this.productId;
|
||||
}
|
||||
|
||||
public void setProductId(Long productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public int getProductType() {
|
||||
return this.productType;
|
||||
}
|
||||
|
||||
public void setProductType(int productType) {
|
||||
this.productType = productType;
|
||||
}
|
||||
|
||||
public int getFinancialAccountType() {
|
||||
return this.financialAccountType;
|
||||
}
|
||||
|
||||
public void setFinancialAccountType(int financialAccountType) {
|
||||
this.financialAccountType = financialAccountType;
|
||||
}
|
||||
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package org.mifosplatform.accounting.domain;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface ProductToGLAccountMappingRepository extends JpaRepository<ProductToGLAccountMapping, Long>,
|
||||
JpaSpecificationExecutor<ProductToGLAccountMapping> {
|
||||
|
||||
ProductToGLAccountMapping findByProductIdAndProductTypeAndFinancialAccountType(Long productId, int productType, int financialAccountType);
|
||||
|
||||
List<ProductToGLAccountMapping> findByProductIdAndProductType(Long productId, int productType);
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package org.mifosplatform.accounting.exceptions;
|
||||
|
||||
import org.mifosplatform.accounting.AccountingConstants.PORTFOLIO_PRODUCT_TYPE;
|
||||
import org.mifosplatform.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 PORTFOLIO_PRODUCT_TYPE type, final Long productId, String accountType) {
|
||||
super("error.msg.productTyAccountMapping.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);
|
||||
}
|
||||
}
|
||||
+3
@@ -2,6 +2,7 @@ package org.mifosplatform.accounting.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.accounting.AccountingConstants;
|
||||
import org.mifosplatform.accounting.api.data.GLAccountData;
|
||||
|
||||
public interface GLAccountReadPlatformService {
|
||||
@@ -11,4 +12,6 @@ public interface GLAccountReadPlatformService {
|
||||
|
||||
GLAccountData retrieveGLAccountById(long glAccountId);
|
||||
|
||||
List<GLAccountData> retrieveAllEnabledDetailGLAccounts(AccountingConstants.GL_ACCOUNT_CLASSIFICATION classification);
|
||||
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package org.mifosplatform.accounting.service;
|
||||
|
||||
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
||||
|
||||
public interface ProductToGLAccountMappingReadPlatformService {
|
||||
|
||||
LoanProductData fetchAccountMappingDetailsForLoanProduct(LoanProductData loanProductData);
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package org.mifosplatform.accounting.service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.mifosplatform.portfolio.loanproduct.command.LoanProductCommand;
|
||||
|
||||
public interface ProductToGLAccountMappingWritePlatformService {
|
||||
|
||||
void createLoanProductToGLAccountMapping(Long loanProductId, LoanProductCommand command);
|
||||
|
||||
Map<String, Object> updateLoanProductToGLAccountMapping(Long loanProductId, LoanProductCommand command, boolean accountingRuleChanged);
|
||||
|
||||
void deleteLoanProductToGLAccountMapping(Long loanProductId);
|
||||
|
||||
}
|
||||
+6
@@ -6,6 +6,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.accounting.AccountingConstants;
|
||||
import org.mifosplatform.accounting.AccountingConstants.GL_ACCOUNT_CLASSIFICATION;
|
||||
import org.mifosplatform.accounting.AccountingConstants.GL_ACCOUNT_USAGE;
|
||||
import org.mifosplatform.accounting.api.data.GLAccountData;
|
||||
@@ -151,6 +152,11 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GLAccountData> retrieveAllEnabledDetailGLAccounts(GL_ACCOUNT_CLASSIFICATION classification) {
|
||||
return retrieveAllGLAccounts(classification.toString(), null, AccountingConstants.GL_ACCOUNT_USAGE.DETAIL.toString(), null, false);
|
||||
}
|
||||
|
||||
private static boolean checkValidGLAccountClassification(final String entityType) {
|
||||
for (GL_ACCOUNT_CLASSIFICATION classification : GL_ACCOUNT_CLASSIFICATION.values()) {
|
||||
if (classification.name().toString().equalsIgnoreCase(entityType)) { return true; }
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package org.mifosplatform.accounting.service.impl;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.accounting.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN;
|
||||
import org.mifosplatform.accounting.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
|
||||
import org.mifosplatform.accounting.api.data.ProductToGLAccountMappingData;
|
||||
import org.mifosplatform.accounting.service.ProductToGLAccountMappingReadPlatformService;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.AccountingRuleType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ProductToGLAccountMappingReadPlatformServiceImpl implements ProductToGLAccountMappingReadPlatformService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Autowired
|
||||
public ProductToGLAccountMappingReadPlatformServiceImpl(final TenantAwareRoutingDataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
private static final class LoanProductToGLAccountMappingMapper implements RowMapper<ProductToGLAccountMappingData> {
|
||||
|
||||
public String schema() {
|
||||
return " id as id, gl_account_id as glAccountId,product_id as productId,product_type as productType,financial_account_type as financialAccountType"
|
||||
+ " from acc_product_mapping " + " where product_type=1 ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProductToGLAccountMappingData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
Long id = rs.getLong("id");
|
||||
Long glAccountId = rs.getLong("glAccountId");
|
||||
Long productId = rs.getLong("productId");
|
||||
Integer productType = rs.getInt("productType");
|
||||
Integer financialAccountType = rs.getInt("financialAccountType");
|
||||
|
||||
return new ProductToGLAccountMappingData(id, glAccountId, productId, productType, financialAccountType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanProductData fetchAccountMappingDetailsForLoanProduct(LoanProductData loanProductData) {
|
||||
LoanProductToGLAccountMappingMapper rm = new LoanProductToGLAccountMappingMapper();
|
||||
String sql = "select " + rm.schema() + " and product_id = ?";
|
||||
List<ProductToGLAccountMappingData> productToGLAccountMappingDatas = this.jdbcTemplate.query(sql, rm,
|
||||
new Object[] { loanProductData.getId() });
|
||||
|
||||
if (loanProductData.getAccountingType() == AccountingRuleType.CASH_BASED.getValue()) {
|
||||
for (ProductToGLAccountMappingData productToGLAccountMappingData : productToGLAccountMappingDatas) {
|
||||
CASH_ACCOUNTS_FOR_LOAN glAccountForLoan = CASH_ACCOUNTS_FOR_LOAN.fromInt(productToGLAccountMappingData
|
||||
.getFinancialAccountType());
|
||||
if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE)) {
|
||||
loanProductData.setFundSourceAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
} else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES)) {
|
||||
loanProductData.setIncomeFromFeeAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
} else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES)) {
|
||||
loanProductData.setIncomeFromPenaltyAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
} else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS)) {
|
||||
loanProductData.setInterestOnLoanAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
} else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO)) {
|
||||
loanProductData.setLoanPortfolioAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
} else if (glAccountForLoan.equals(CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF)) {
|
||||
loanProductData.setWriteOffAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
}
|
||||
}
|
||||
} else if (loanProductData.getAccountingType() == AccountingRuleType.ACCRUAL_BASED.getValue()) {
|
||||
for (ProductToGLAccountMappingData productToGLAccountMappingData : productToGLAccountMappingDatas) {
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN glAccountForLoan = ACCRUAL_ACCOUNTS_FOR_LOAN.fromInt(productToGLAccountMappingData
|
||||
.getFinancialAccountType());
|
||||
if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE)) {
|
||||
loanProductData.setFundSourceAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
} else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES)) {
|
||||
loanProductData.setIncomeFromFeeAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
} else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES)) {
|
||||
loanProductData.setIncomeFromPenaltyAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
} else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS)) {
|
||||
loanProductData.setInterestOnLoanAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
} else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO)) {
|
||||
loanProductData.setLoanPortfolioAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
} else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF)) {
|
||||
loanProductData.setWriteOffAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
} else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE)) {
|
||||
loanProductData.setReceivableInterestAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
} else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE)) {
|
||||
loanProductData.setReceivableFeeAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
} else if (glAccountForLoan.equals(ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE)) {
|
||||
loanProductData.setReceivablePenaltyAccountId(productToGLAccountMappingData.getGlAccountId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return loanProductData;
|
||||
}
|
||||
|
||||
}
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
package org.mifosplatform.accounting.service.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mifosplatform.accounting.AccountingConstants;
|
||||
import org.mifosplatform.accounting.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN;
|
||||
import org.mifosplatform.accounting.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
|
||||
import org.mifosplatform.accounting.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
|
||||
import org.mifosplatform.accounting.AccountingConstants.PORTFOLIO_PRODUCT_TYPE;
|
||||
import org.mifosplatform.accounting.domain.GLAccount;
|
||||
import org.mifosplatform.accounting.domain.GLAccountRepository;
|
||||
import org.mifosplatform.accounting.domain.ProductToGLAccountMapping;
|
||||
import org.mifosplatform.accounting.domain.ProductToGLAccountMappingRepository;
|
||||
import org.mifosplatform.accounting.exceptions.GLAccountNotFoundException;
|
||||
import org.mifosplatform.accounting.exceptions.ProductToGLAccountMappingNotFoundException;
|
||||
import org.mifosplatform.accounting.service.ProductToGLAccountMappingWritePlatformService;
|
||||
import org.mifosplatform.portfolio.loanproduct.command.LoanProductCommand;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.AccountingRuleType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class ProductToGLAccountMappingWritePlatformServiceImpl implements ProductToGLAccountMappingWritePlatformService {
|
||||
|
||||
private final GLAccountRepository accountRepository;
|
||||
private final ProductToGLAccountMappingRepository accountMappingRepository;
|
||||
|
||||
@Autowired
|
||||
public ProductToGLAccountMappingWritePlatformServiceImpl(final GLAccountRepository glAccountRepository,
|
||||
final ProductToGLAccountMappingRepository glAccountMappingRepository) {
|
||||
this.accountRepository = glAccountRepository;
|
||||
this.accountMappingRepository = glAccountMappingRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void createLoanProductToGLAccountMapping(Long loanProductId, LoanProductCommand command) {
|
||||
AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(command.getAccountingType());
|
||||
|
||||
if (accountingRuleType.equals(AccountingRuleType.NONE)) {
|
||||
return;
|
||||
} else if (accountingRuleType.equals(AccountingRuleType.CASH_BASED)) {
|
||||
// asset
|
||||
saveLoanToAccountMapping(command.getFundAccountId(), loanProductId, CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue());
|
||||
saveLoanToAccountMapping(command.getLoanPortfolioAccountId(), loanProductId, CASH_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.getValue());
|
||||
saveLoanToAccountMapping(command.getInterestOnLoanId(), loanProductId, CASH_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.getValue());
|
||||
|
||||
// income
|
||||
saveLoanToAccountMapping(command.getIncomeFromFeeId(), loanProductId, CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue());
|
||||
saveLoanToAccountMapping(command.getIncomeFromPenaltyId(), loanProductId,
|
||||
CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue());
|
||||
|
||||
// expenses
|
||||
saveLoanToAccountMapping(command.getWriteOffAccountId(), loanProductId,
|
||||
CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue());
|
||||
} else if (accountingRuleType.equals(AccountingRuleType.ACCRUAL_BASED)) {
|
||||
// assets (including receivables)
|
||||
saveLoanToAccountMapping(command.getFundAccountId(), loanProductId, ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue());
|
||||
saveLoanToAccountMapping(command.getLoanPortfolioAccountId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.getValue());
|
||||
saveLoanToAccountMapping(command.getInterestOnLoanId(), loanProductId, ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.getValue());
|
||||
|
||||
saveLoanToAccountMapping(command.getReceivableInterestAccountId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE.getValue());
|
||||
saveLoanToAccountMapping(command.getReceivableFeeAccountId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE.getValue());
|
||||
saveLoanToAccountMapping(command.getReceivablePenaltyAccountId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE.getValue());
|
||||
|
||||
// income
|
||||
saveLoanToAccountMapping(command.getIncomeFromFeeId(), loanProductId, ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue());
|
||||
saveLoanToAccountMapping(command.getIncomeFromPenaltyId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue());
|
||||
|
||||
// expenses
|
||||
saveLoanToAccountMapping(command.getWriteOffAccountId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Map<String, Object> updateLoanProductToGLAccountMapping(Long loanProductId, LoanProductCommand command,
|
||||
boolean accountingRuleChanged) {
|
||||
Map<String, Object> changes = new HashMap<String, Object>();
|
||||
AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(command.getAccountingType());
|
||||
if (accountingRuleChanged) {
|
||||
deleteLoanProductToGLAccountMapping(loanProductId);
|
||||
createLoanProductToGLAccountMapping(loanProductId, command);
|
||||
if (accountingRuleType.equals(AccountingRuleType.CASH_BASED)) {
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), command.getFundAccountId());
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), command.getLoanPortfolioAccountId());
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), command.getInterestOnLoanId());
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), command.getIncomeFromFeeId());
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), command.getIncomeFromPenaltyId());
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), command.getWriteOffAccountId());
|
||||
} else if (accountingRuleType.equals(AccountingRuleType.ACCRUAL_BASED)) {
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), command.getFundAccountId());
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), command.getLoanPortfolioAccountId());
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), command.getInterestOnLoanId());
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), command.getIncomeFromFeeId());
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), command.getIncomeFromPenaltyId());
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), command.getWriteOffAccountId());
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(), command.getReceivableInterestAccountId());
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), command.getReceivableFeeAccountId());
|
||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(), command.getReceivablePenaltyAccountId());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (accountingRuleType.equals(AccountingRuleType.NONE)) {
|
||||
// do nothing
|
||||
} else if (accountingRuleType.equals(AccountingRuleType.CASH_BASED)) {
|
||||
// asset
|
||||
updateLoanToAccountMapping(command.getFundAccountId(), loanProductId, CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue(),
|
||||
CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.toString(), LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), changes);
|
||||
updateLoanToAccountMapping(command.getLoanPortfolioAccountId(), loanProductId,
|
||||
CASH_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.getValue(), CASH_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.toString(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), changes);
|
||||
updateLoanToAccountMapping(command.getInterestOnLoanId(), loanProductId,
|
||||
CASH_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.getValue(), CASH_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.toString(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), changes);
|
||||
|
||||
// income
|
||||
updateLoanToAccountMapping(command.getIncomeFromFeeId(), loanProductId, CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue(),
|
||||
CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.toString(), LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
|
||||
changes);
|
||||
updateLoanToAccountMapping(command.getIncomeFromPenaltyId(), loanProductId,
|
||||
CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue(), CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.toString(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), changes);
|
||||
|
||||
// expenses
|
||||
updateLoanToAccountMapping(command.getWriteOffAccountId(), loanProductId,
|
||||
CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue(), CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.toString(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), changes);
|
||||
} else if (accountingRuleType.equals(AccountingRuleType.ACCRUAL_BASED)) {
|
||||
// assets (including receivables)
|
||||
updateLoanToAccountMapping(command.getFundAccountId(), loanProductId, ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue(),
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE.toString(), LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), changes);
|
||||
updateLoanToAccountMapping(command.getLoanPortfolioAccountId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.toString(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), changes);
|
||||
updateLoanToAccountMapping(command.getInterestOnLoanId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.toString(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), changes);
|
||||
|
||||
updateLoanToAccountMapping(command.getReceivableInterestAccountId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE.toString(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(), changes);
|
||||
updateLoanToAccountMapping(command.getReceivableFeeAccountId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE.toString(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), changes);
|
||||
updateLoanToAccountMapping(command.getReceivablePenaltyAccountId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE.getValue(),
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE.toString(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(), changes);
|
||||
|
||||
// income
|
||||
updateLoanToAccountMapping(command.getIncomeFromFeeId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.toString(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), changes);
|
||||
updateLoanToAccountMapping(command.getIncomeFromPenaltyId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue(),
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.toString(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), changes);
|
||||
|
||||
// expenses
|
||||
updateLoanToAccountMapping(command.getWriteOffAccountId(), loanProductId,
|
||||
ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.toString(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), changes);
|
||||
}
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
private void saveLoanToAccountMapping(Long glAccountId, Long productId, int accountTypeId) {
|
||||
GLAccount glAccount = accountRepository.findOne(glAccountId);
|
||||
if (glAccount == null) { throw new GLAccountNotFoundException(glAccountId); }
|
||||
ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping(glAccount, productId,
|
||||
AccountingConstants.PORTFOLIO_PRODUCT_TYPE.LOAN.getValue(), accountTypeId);
|
||||
accountMappingRepository.save(accountMapping);
|
||||
}
|
||||
|
||||
private void updateLoanToAccountMapping(Long glAccountId, Long productId, int accountTypeId, String accountTypeName,
|
||||
String accountParamValue, Map<String, Object> changes) {
|
||||
// get the existing product
|
||||
ProductToGLAccountMapping accountMapping = accountMappingRepository.findByProductIdAndProductTypeAndFinancialAccountType(productId,
|
||||
PORTFOLIO_PRODUCT_TYPE.LOAN.getValue(), accountTypeId);
|
||||
if (accountMapping == null) { throw new ProductToGLAccountMappingNotFoundException(PORTFOLIO_PRODUCT_TYPE.LOAN, productId,
|
||||
accountTypeName); }
|
||||
if (accountMapping.getGlAccount().getId() != glAccountId) {
|
||||
GLAccount glAccount = accountRepository.findOne(glAccountId);
|
||||
if (glAccount == null) { throw new GLAccountNotFoundException(glAccountId); }
|
||||
changes.put(accountParamValue, glAccountId);
|
||||
accountMapping.setGlAccount(glAccount);
|
||||
accountMappingRepository.save(accountMapping);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteLoanProductToGLAccountMapping(Long loanProductId) {
|
||||
List<ProductToGLAccountMapping> productToGLAccountMappings = accountMappingRepository.findByProductIdAndProductType(loanProductId,
|
||||
PORTFOLIO_PRODUCT_TYPE.LOAN.getValue());
|
||||
if (productToGLAccountMappings != null && productToGLAccountMappings.size() > 0) {
|
||||
accountMappingRepository.deleteInBatch(productToGLAccountMappings);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -57,6 +57,6 @@ public class LoanProductRelatedDetailAssembler {
|
||||
|
||||
return new LoanProductRelatedDetail(currency, principalAmount, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
|
||||
defaultNumberOfInstallments, amortizationMethod, inArrearsTolerance);
|
||||
defaultNumberOfInstallments, amortizationMethod, inArrearsTolerance, null);
|
||||
}
|
||||
}
|
||||
+28
-4
@@ -17,8 +17,16 @@ import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
|
||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||
import org.mifosplatform.commands.service.CommandWrapperBuilder;
|
||||
|
||||
import org.mifosplatform.accounting.AccountingConstants.GL_ACCOUNT_CLASSIFICATION;
|
||||
import org.mifosplatform.accounting.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
|
||||
import org.mifosplatform.accounting.api.data.GLAccountData;
|
||||
import org.mifosplatform.accounting.service.GLAccountReadPlatformService;
|
||||
import org.mifosplatform.accounting.service.ProductToGLAccountMappingReadPlatformService;
|
||||
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
@@ -51,7 +59,10 @@ public class LoanProductsApiResource {
|
||||
"interestRateFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType", "charges", "createdOn",
|
||||
"lastModifedOn", "currencyOptions", "amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions",
|
||||
"repaymentFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "fundOptions", "transactionProcessingStrategyOptions",
|
||||
"chargeOptions"));
|
||||
"chargeOptions", "assetAccountOptions", "incomeAccountOptions", "expenseAccountOptions", "accountingType" , LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(),LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(),LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(),LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(),LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue()));
|
||||
|
||||
private final String resourceNameForPermissions = "LOANPRODUCT";
|
||||
|
||||
@@ -64,6 +75,8 @@ public class LoanProductsApiResource {
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final LoanDropdownReadPlatformService dropdownReadPlatformService;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
private final GLAccountReadPlatformService accountReadPlatformService;
|
||||
private final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
public LoanProductsApiResource(final PlatformSecurityContext context, final LoanProductReadPlatformService readPlatformService,
|
||||
@@ -71,7 +84,9 @@ public class LoanProductsApiResource {
|
||||
final FundReadPlatformService fundReadPlatformService, final LoanDropdownReadPlatformService dropdownReadPlatformService,
|
||||
final DefaultToApiJsonSerializer<LoanProductData> toApiJsonSerializer,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||
final GLAccountReadPlatformService accountReadPlatformService,
|
||||
final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService) {
|
||||
this.context = context;
|
||||
this.loanProductReadPlatformService = readPlatformService;
|
||||
this.chargeReadPlatformService = chargeReadPlatformService;
|
||||
@@ -81,6 +96,8 @@ public class LoanProductsApiResource {
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
this.accountReadPlatformService = accountReadPlatformService;
|
||||
this.accountMappingReadPlatformService = accountMappingReadPlatformService;
|
||||
}
|
||||
|
||||
@POST
|
||||
@@ -137,8 +154,10 @@ public class LoanProductsApiResource {
|
||||
if (settings.isTemplate()) {
|
||||
loanProduct = handleTemplate(loanProduct);
|
||||
}
|
||||
|
||||
LoanProductData loanProductDataUpdatedWithAccountingMapping=accountMappingReadPlatformService.fetchAccountMappingDetailsForLoanProduct(loanProduct);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(settings, loanProduct, LOAN_PRODUCT_DATA_PARAMETERS);
|
||||
return this.toApiJsonSerializer.serialize(settings, loanProductDataUpdatedWithAccountingMapping, LOAN_PRODUCT_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@@ -174,9 +193,14 @@ public class LoanProductsApiResource {
|
||||
final Collection<FundData> fundOptions = this.fundReadPlatformService.retrieveAllFunds();
|
||||
final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions = this.dropdownReadPlatformService
|
||||
.retreiveTransactionProcessingStrategies();
|
||||
|
||||
final List<GLAccountData> assetAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GL_ACCOUNT_CLASSIFICATION.ASSET);
|
||||
final List<GLAccountData> incomeAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GL_ACCOUNT_CLASSIFICATION.INCOME);;
|
||||
final List<GLAccountData> expenseAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GL_ACCOUNT_CLASSIFICATION.EXPENSE);;
|
||||
|
||||
return new LoanProductData(productData, chargeOptions, currencyOptions, amortizationTypeOptions, interestTypeOptions,
|
||||
interestCalculationPeriodTypeOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions,
|
||||
interestRateFrequencyTypeOptions, fundOptions, transactionProcessingStrategyOptions);
|
||||
interestRateFrequencyTypeOptions, fundOptions, transactionProcessingStrategyOptions,
|
||||
assetAccountOptions, incomeAccountOptions, expenseAccountOptions);
|
||||
}
|
||||
}
|
||||
+154
-12
@@ -4,9 +4,11 @@ import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.accounting.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.AccountingRuleType;
|
||||
|
||||
/**
|
||||
* Immutable command for creating or updating details of a loan product.
|
||||
@@ -31,11 +33,28 @@ public class LoanProductCommand {
|
||||
private final Integer interestCalculationPeriodType;
|
||||
private final String[] charges;
|
||||
|
||||
// accounting fields
|
||||
private final Integer accountingType;
|
||||
// accounting heads used for cash/accrual based accounting
|
||||
private final Long loanPortfolioAccountId;
|
||||
private final Long fundAccountId;
|
||||
private final Long interestOnLoanId;
|
||||
private final Long incomeFromFeeId;
|
||||
private final Long incomeFromPenaltyId;
|
||||
private final Long writeOffAccountId;
|
||||
// accounting heads used only for accrual based accounting
|
||||
private final Long receivableInterestAccountId;
|
||||
private final Long receivableFeeAccountId;
|
||||
private final Long receivablePenaltyAccountId;
|
||||
|
||||
public LoanProductCommand(final String name, final String description, final Long fundId, final Long transactionProcessingStrategyId,
|
||||
final String currencyCode, final Integer digitsAfterDecimal, final BigDecimal principal, final BigDecimal inArrearsTolerance,
|
||||
final Integer numberOfRepayments, final Integer repaymentEvery, final BigDecimal interestRatePerPeriod,
|
||||
final Integer repaymentFrequencyType, final Integer interestRateFrequencyType, final Integer amortizationType,
|
||||
final Integer interestType, final Integer interestCalculationPeriodType, final String[] charges) {
|
||||
final Integer interestType, final Integer interestCalculationPeriodType, final String[] charges, final Integer accountingType,
|
||||
final Long loanPortfolioAccountId, final Long fundAccountId, final Long interestOnLoanId, final Long incomeFromFeeId,
|
||||
final Long incomeFromPenaltyId, final Long writeOffAccountId, final Long receivableInterestAccountId,
|
||||
final Long receivableFeeAccountId, final Long receivablePenaltyAccountId) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.fundId = fundId;
|
||||
@@ -57,6 +76,18 @@ public class LoanProductCommand {
|
||||
this.interestType = interestType;
|
||||
this.interestCalculationPeriodType = interestCalculationPeriodType;
|
||||
this.charges = charges;
|
||||
this.accountingType = accountingType;
|
||||
// accounting heads used for cash/accrual based accounting
|
||||
this.loanPortfolioAccountId = loanPortfolioAccountId;
|
||||
this.fundAccountId = fundAccountId;
|
||||
this.interestOnLoanId = interestOnLoanId;
|
||||
this.incomeFromFeeId = incomeFromFeeId;
|
||||
this.incomeFromPenaltyId = incomeFromPenaltyId;
|
||||
this.writeOffAccountId = writeOffAccountId;
|
||||
// accounting heads used only for accrual based accounting
|
||||
this.receivableInterestAccountId = receivableInterestAccountId;
|
||||
this.receivableFeeAccountId = receivableFeeAccountId;
|
||||
this.receivablePenaltyAccountId = receivablePenaltyAccountId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -127,6 +158,55 @@ public class LoanProductCommand {
|
||||
return charges;
|
||||
}
|
||||
|
||||
public Integer getAccountingType() {
|
||||
return this.accountingType;
|
||||
}
|
||||
|
||||
|
||||
public Long getLoanPortfolioAccountId() {
|
||||
return this.loanPortfolioAccountId;
|
||||
}
|
||||
|
||||
|
||||
public Long getFundAccountId() {
|
||||
return this.fundAccountId;
|
||||
}
|
||||
|
||||
|
||||
public Long getInterestOnLoanId() {
|
||||
return this.interestOnLoanId;
|
||||
}
|
||||
|
||||
|
||||
public Long getIncomeFromFeeId() {
|
||||
return this.incomeFromFeeId;
|
||||
}
|
||||
|
||||
|
||||
public Long getIncomeFromPenaltyId() {
|
||||
return this.incomeFromPenaltyId;
|
||||
}
|
||||
|
||||
|
||||
public Long getWriteOffAccountId() {
|
||||
return this.writeOffAccountId;
|
||||
}
|
||||
|
||||
|
||||
public Long getReceivableInterestAccountId() {
|
||||
return this.receivableInterestAccountId;
|
||||
}
|
||||
|
||||
|
||||
public Long getReceivableFeeAccountId() {
|
||||
return this.receivableFeeAccountId;
|
||||
}
|
||||
|
||||
|
||||
public Long getReceivablePenaltyAccountId() {
|
||||
return this.receivablePenaltyAccountId;
|
||||
}
|
||||
|
||||
public void validateForCreate() {
|
||||
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
@@ -154,6 +234,38 @@ public class LoanProductCommand {
|
||||
baseDataValidator.reset().parameter("interestCalculationPeriodType").value(this.interestCalculationPeriodType).notNull()
|
||||
.inMinMaxRange(0, 1);
|
||||
|
||||
// validation for accounting rules
|
||||
baseDataValidator.reset().parameter("accountingType").value(this.accountingType).notNull().inMinMaxRange(1,3);
|
||||
if (this.getAccountingType() != null) {
|
||||
/**
|
||||
* validation for heads applicable for both cash and accrual based
|
||||
* accounting
|
||||
**/
|
||||
if (this.getAccountingType().equals(AccountingRuleType.CASH_BASED.getValue())
|
||||
|| this.getAccountingType().equals(AccountingRuleType.ACCRUAL_BASED.getValue())) {
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue())
|
||||
.value(this.loanPortfolioAccountId).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue()).value(this.fundAccountId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue())
|
||||
.value(this.interestOnLoanId).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue()).value(this.incomeFromFeeId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue())
|
||||
.value(this.incomeFromPenaltyId).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue())
|
||||
.value(this.writeOffAccountId).notNull().integerGreaterThanZero();
|
||||
}// validation for accrual based accounting specific heads
|
||||
if (this.getAccountingType().equals(AccountingRuleType.ACCRUAL_BASED.getValue())) {
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue())
|
||||
.value(this.receivableInterestAccountId).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue())
|
||||
.value(this.receivableFeeAccountId).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue())
|
||||
.value(this.receivablePenaltyAccountId).notNull().integerGreaterThanZero();
|
||||
}
|
||||
}
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
@@ -182,20 +294,50 @@ public class LoanProductCommand {
|
||||
.integerGreaterThanZero();
|
||||
|
||||
baseDataValidator.reset().parameter("interestRatePerPeriod").value(this.interestRatePerPeriod).ignoreIfNull().notBlank();
|
||||
baseDataValidator.reset().parameter("interestRateFrequencyType").value(this.interestRateFrequencyType).ignoreIfNull()
|
||||
.notNull().inMinMaxRange(0, 3);
|
||||
baseDataValidator.reset().parameter("interestRateFrequencyType").value(this.interestRateFrequencyType).ignoreIfNull().notNull()
|
||||
.inMinMaxRange(0, 3);
|
||||
|
||||
baseDataValidator.reset().parameter("amortizationType").value(this.amortizationType).ignoreIfNull().notNull()
|
||||
.inMinMaxRange(0, 1);
|
||||
baseDataValidator.reset().parameter("amortizationType").value(this.amortizationType).ignoreIfNull().notNull().inMinMaxRange(0, 1);
|
||||
baseDataValidator.reset().parameter("interestType").value(this.interestType).ignoreIfNull().notNull().inMinMaxRange(0, 1);
|
||||
baseDataValidator.reset().parameter("interestCalculationPeriodType").value(this.interestCalculationPeriodType)
|
||||
.ignoreIfNull().notNull().inMinMaxRange(0, 1);
|
||||
baseDataValidator.reset().parameter("interestCalculationPeriodType").value(this.interestCalculationPeriodType).ignoreIfNull()
|
||||
.notNull().inMinMaxRange(0, 1);
|
||||
|
||||
baseDataValidator.reset().anyOfNotNull(this.fundId, this.transactionProcessingStrategyId, this.name,
|
||||
this.description, this.currencyCode, this.digitsAfterDecimal, this.principal,
|
||||
this.inArrearsTolerance, this.repaymentFrequencyType, this.repaymentEvery,
|
||||
this.numberOfRepayments, this.interestRatePerPeriod, this.interestRateFrequencyType,
|
||||
this.amortizationType, this.interestType, this.interestCalculationPeriodType, this.charges);
|
||||
// validation for accounting rules
|
||||
baseDataValidator.reset().parameter("accountingType").value(this.accountingType).ignoreIfNull().inMinMaxRange(1, 3);
|
||||
if (this.getAccountingType() != null) {
|
||||
/**
|
||||
* validation for heads applicable for both cash and accrual based
|
||||
* accounting
|
||||
**/
|
||||
if (this.getAccountingType().equals(AccountingRuleType.CASH_BASED.getValue())
|
||||
|| this.getAccountingType().equals(AccountingRuleType.ACCRUAL_BASED.getValue())) {
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue())
|
||||
.value(this.loanPortfolioAccountId).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue()).value(this.fundAccountId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue())
|
||||
.value(this.interestOnLoanId).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue()).value(this.incomeFromFeeId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue())
|
||||
.value(this.incomeFromPenaltyId).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue())
|
||||
.value(this.writeOffAccountId).notNull().integerGreaterThanZero();
|
||||
}// validation for accrual based accounting specific heads
|
||||
if (this.getAccountingType().equals(AccountingRuleType.ACCRUAL_BASED.getValue())) {
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue())
|
||||
.value(this.receivableInterestAccountId).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue())
|
||||
.value(this.receivableFeeAccountId).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue())
|
||||
.value(this.receivablePenaltyAccountId).notNull().integerGreaterThanZero();
|
||||
}
|
||||
}
|
||||
|
||||
baseDataValidator.reset().anyOfNotNull(this.fundId, this.transactionProcessingStrategyId, this.name, this.description,
|
||||
this.currencyCode, this.digitsAfterDecimal, this.principal, this.inArrearsTolerance, this.repaymentFrequencyType,
|
||||
this.repaymentEvery, this.numberOfRepayments, this.interestRatePerPeriod, this.interestRateFrequencyType,
|
||||
this.amortizationType, this.interestType, this.interestCalculationPeriodType, this.charges, this.accountingType);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
|
||||
+144
-4
@@ -6,6 +6,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.mifosplatform.accounting.api.data.GLAccountData;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||
@@ -40,6 +41,7 @@ public class LoanProductData {
|
||||
private final Integer repaymentEvery;
|
||||
private final BigDecimal interestRatePerPeriod;
|
||||
private final BigDecimal annualInterestRate;
|
||||
private final Integer accountingType;
|
||||
|
||||
private final EnumOptionData loanTermFrequencyType;
|
||||
private final EnumOptionData repaymentFrequencyType;
|
||||
@@ -64,6 +66,23 @@ public class LoanProductData {
|
||||
private final List<EnumOptionData> loanTermFrequencyTypeOptions;
|
||||
private final Collection<ChargeData> chargeOptions;
|
||||
|
||||
// accounting related template fields
|
||||
private final List<GLAccountData> assetAccountOptions;
|
||||
private final List<GLAccountData> incomeAccountOptions;
|
||||
private final List<GLAccountData> expenseAccountOptions;
|
||||
|
||||
//accounting related mapping feilds
|
||||
private Long loanPortfolioAccountId;
|
||||
private Long fundSourceAccountId;
|
||||
private Long interestOnLoanAccountId;
|
||||
private Long incomeFromFeeAccountId;
|
||||
private Long incomeFromPenaltyAccountId;
|
||||
private Long writeOffAccountId;
|
||||
// accounting heads used only for accrual based accounting
|
||||
private Long receivableInterestAccountId;
|
||||
private Long receivableFeeAccountId;
|
||||
private Long receivablePenaltyAccountId;
|
||||
|
||||
/**
|
||||
* Used when returning lookup information about loan product for dropdowns.
|
||||
*/
|
||||
@@ -90,11 +109,12 @@ public class LoanProductData {
|
||||
final Long transactionProcessingStrategyId = null;
|
||||
final String transactionProcessingStrategyName = null;
|
||||
final Collection<ChargeData> charges = null;
|
||||
final Integer accountingType = null;
|
||||
|
||||
return new LoanProductData(createdOn, lastModifedOn, id, name, description, currency, principal, tolerance, numberOfRepayments,
|
||||
loanTermFrequency, repaymentEvery, interestRatePerPeriod, annualInterestRate, loanTermFrequencyType,
|
||||
repaymentFrequencyType, interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, fundId,
|
||||
fundName, transactionProcessingStrategyId, transactionProcessingStrategyName, charges);
|
||||
fundName, transactionProcessingStrategyId, transactionProcessingStrategyName, charges, accountingType);
|
||||
}
|
||||
|
||||
public static LoanProductData sensibleDefaultsForNewLoanProductCreation() {
|
||||
@@ -124,11 +144,12 @@ public class LoanProductData {
|
||||
final Long transactionProcessingStrategyId = null;
|
||||
final String transactionProcessingStrategyName = null;
|
||||
final Collection<ChargeData> charges = null;
|
||||
final Integer accountingType = 1;
|
||||
|
||||
return new LoanProductData(createdOn, lastModifedOn, id, name, description, currency, principal, tolerance, numberOfRepayments,
|
||||
loanTermFrequency, repaymentEvery, interestRatePerPeriod, annualInterestRate, loanTermFrequencyType,
|
||||
repaymentFrequencyType, interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, fundId,
|
||||
fundName, transactionProcessingStrategyId, transactionProcessingStrategyName, charges);
|
||||
fundName, transactionProcessingStrategyId, transactionProcessingStrategyName, charges, accountingType);
|
||||
}
|
||||
|
||||
public LoanProductData(final DateTime createdOn, final DateTime lastModifedOn, final Long id, final String name,
|
||||
@@ -138,7 +159,7 @@ public class LoanProductData {
|
||||
final EnumOptionData repaymentFrequencyType, final EnumOptionData interestRateFrequencyType,
|
||||
final EnumOptionData amortizationType, final EnumOptionData interestType, final EnumOptionData interestCalculationPeriodType,
|
||||
final Long fundId, final String fundName, final Long transactionProcessingStrategyId,
|
||||
final String transactionProcessingStrategyName, final Collection<ChargeData> charges) {
|
||||
final String transactionProcessingStrategyName, final Collection<ChargeData> charges, final Integer accountingType) {
|
||||
this.createdOn = createdOn;
|
||||
this.lastModifedOn = lastModifedOn;
|
||||
this.id = id;
|
||||
@@ -163,6 +184,7 @@ public class LoanProductData {
|
||||
this.transactionProcessingStrategyId = transactionProcessingStrategyId;
|
||||
this.transactionProcessingStrategyName = transactionProcessingStrategyName;
|
||||
this.charges = charges;
|
||||
this.accountingType = accountingType;
|
||||
|
||||
this.chargeOptions = null;
|
||||
this.currencyOptions = null;
|
||||
@@ -174,6 +196,10 @@ public class LoanProductData {
|
||||
this.loanTermFrequencyTypeOptions = null;
|
||||
this.repaymentFrequencyTypeOptions = null;
|
||||
this.interestRateFrequencyTypeOptions = null;
|
||||
|
||||
this.assetAccountOptions = null;
|
||||
this.incomeAccountOptions = null;
|
||||
this.expenseAccountOptions = null;
|
||||
}
|
||||
|
||||
public LoanProductData(final LoanProductData productData, final Collection<ChargeData> chargeOptions,
|
||||
@@ -181,7 +207,9 @@ public class LoanProductData {
|
||||
final List<EnumOptionData> interestTypeOptions, final List<EnumOptionData> interestCalculationPeriodTypeOptions,
|
||||
final List<EnumOptionData> loanTermFrequencyTypeOptions, final List<EnumOptionData> repaymentFrequencyTypeOptions,
|
||||
final List<EnumOptionData> interestRateFrequencyTypeOptions, final Collection<FundData> fundOptions,
|
||||
final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions) {
|
||||
final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions,
|
||||
final List<GLAccountData> assetAccountOptions, final List<GLAccountData> incomeAccountOptions,
|
||||
final List<GLAccountData> expenseAccountOptions) {
|
||||
this.createdOn = productData.createdOn;
|
||||
this.lastModifedOn = productData.lastModifedOn;
|
||||
this.id = productData.id;
|
||||
@@ -205,6 +233,7 @@ public class LoanProductData {
|
||||
this.transactionProcessingStrategyId = productData.transactionProcessingStrategyId;
|
||||
this.transactionProcessingStrategyName = productData.transactionProcessingStrategyName;
|
||||
this.charges = productData.charges();
|
||||
this.accountingType = productData.accountingType;
|
||||
|
||||
this.chargeOptions = chargeOptions;
|
||||
this.currencyOptions = currencyOptions;
|
||||
@@ -221,6 +250,10 @@ public class LoanProductData {
|
||||
this.loanTermFrequencyTypeOptions = loanTermFrequencyTypeOptions;
|
||||
this.repaymentFrequencyTypeOptions = repaymentFrequencyTypeOptions;
|
||||
this.interestRateFrequencyTypeOptions = interestRateFrequencyTypeOptions;
|
||||
|
||||
this.assetAccountOptions = assetAccountOptions;
|
||||
this.incomeAccountOptions = incomeAccountOptions;
|
||||
this.expenseAccountOptions = expenseAccountOptions;
|
||||
}
|
||||
|
||||
public Collection<ChargeData> charges() {
|
||||
@@ -362,4 +395,111 @@ public class LoanProductData {
|
||||
public Collection<ChargeData> getChargeOptions() {
|
||||
return chargeOptions;
|
||||
}
|
||||
|
||||
public List<GLAccountData> getAssetAccountOptions() {
|
||||
return this.assetAccountOptions;
|
||||
}
|
||||
|
||||
public List<GLAccountData> getIncomeAccountOptions() {
|
||||
return this.incomeAccountOptions;
|
||||
}
|
||||
|
||||
public List<GLAccountData> getExpenseAccountOptions() {
|
||||
return this.expenseAccountOptions;
|
||||
}
|
||||
|
||||
|
||||
public Long getLoanPortfolioAccountId() {
|
||||
return this.loanPortfolioAccountId;
|
||||
}
|
||||
|
||||
|
||||
public void setLoanPortfolioAccountId(Long loanPortfolioAccountId) {
|
||||
this.loanPortfolioAccountId = loanPortfolioAccountId;
|
||||
}
|
||||
|
||||
|
||||
public Long getFundSourceAccountId() {
|
||||
return this.fundSourceAccountId;
|
||||
}
|
||||
|
||||
|
||||
public void setFundSourceAccountId(Long fundSourceAccountId) {
|
||||
this.fundSourceAccountId = fundSourceAccountId;
|
||||
}
|
||||
|
||||
public Long getInterestOnLoanAccountId() {
|
||||
return this.interestOnLoanAccountId;
|
||||
}
|
||||
|
||||
|
||||
public void setInterestOnLoanAccountId(Long interestOnLoanAccountId) {
|
||||
this.interestOnLoanAccountId = interestOnLoanAccountId;
|
||||
}
|
||||
|
||||
|
||||
public Long getIncomeFromFeeAccountId() {
|
||||
return this.incomeFromFeeAccountId;
|
||||
}
|
||||
|
||||
|
||||
public void setIncomeFromFeeAccountId(Long incomeFromFeeAccountId) {
|
||||
this.incomeFromFeeAccountId = incomeFromFeeAccountId;
|
||||
}
|
||||
|
||||
|
||||
public Long getIncomeFromPenaltyAccountId() {
|
||||
return this.incomeFromPenaltyAccountId;
|
||||
}
|
||||
|
||||
|
||||
public void setIncomeFromPenaltyAccountId(Long incomeFromPenaltyAccountId) {
|
||||
this.incomeFromPenaltyAccountId = incomeFromPenaltyAccountId;
|
||||
}
|
||||
|
||||
public Long getWriteOffAccountId() {
|
||||
return this.writeOffAccountId;
|
||||
}
|
||||
|
||||
|
||||
public void setWriteOffAccountId(Long writeOffAccountId) {
|
||||
this.writeOffAccountId = writeOffAccountId;
|
||||
}
|
||||
|
||||
|
||||
public Long getReceivableInterestAccountId() {
|
||||
return this.receivableInterestAccountId;
|
||||
}
|
||||
|
||||
|
||||
public void setReceivableInterestAccountId(Long receivableInterestAccountId) {
|
||||
this.receivableInterestAccountId = receivableInterestAccountId;
|
||||
}
|
||||
|
||||
|
||||
public Long getReceivableFeeAccountId() {
|
||||
return this.receivableFeeAccountId;
|
||||
}
|
||||
|
||||
|
||||
public void setReceivableFeeAccountId(Long receivableFeeAccountId) {
|
||||
this.receivableFeeAccountId = receivableFeeAccountId;
|
||||
}
|
||||
|
||||
|
||||
public Long getReceivablePenaltyAccountId() {
|
||||
return this.receivablePenaltyAccountId;
|
||||
}
|
||||
|
||||
|
||||
public void setReceivablePenaltyAccountId(Long receivablePenaltyAccountId) {
|
||||
this.receivablePenaltyAccountId = receivablePenaltyAccountId;
|
||||
}
|
||||
|
||||
|
||||
public Integer getAccountingType() {
|
||||
return this.accountingType;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package org.mifosplatform.portfolio.loanproduct.domain;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum AccountingRuleType {
|
||||
|
||||
NONE(1), CASH_BASED(2), ACCRUAL_BASED(3);
|
||||
|
||||
private final Integer value;
|
||||
|
||||
private AccountingRuleType(final Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
private static final Map<Integer, AccountingRuleType> intToEnumMap = new HashMap<Integer, AccountingRuleType>();
|
||||
static {
|
||||
for (AccountingRuleType type : AccountingRuleType.values()) {
|
||||
intToEnumMap.put(type.value, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static AccountingRuleType fromInt(int i) {
|
||||
AccountingRuleType type = intToEnumMap.get(Integer.valueOf(i));
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
||||
+6
-3
@@ -83,10 +83,12 @@ public class LoanProduct extends AbstractAuditableCustom<AppUser, Long> {
|
||||
final Integer repaymentEvery = command.integerValueOfParameterNamed("repaymentEvery");
|
||||
final Integer numberOfRepayments = command.integerValueOfParameterNamed("numberOfRepayments");
|
||||
final BigDecimal inArrearsTolerance = command.bigDecimalValueOfParameterNamed("inArrearsTolerance");
|
||||
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(command
|
||||
.integerValueOfParameterNamed("accountingType"));
|
||||
|
||||
return new LoanProduct(fund, loanTransactionProcessingStrategy, name, description, currency, principal, interestRatePerPeriod,
|
||||
interestFrequencyType, annualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery,
|
||||
repaymentFrequencyType, numberOfRepayments, amortizationMethod, inArrearsTolerance, productCharges);
|
||||
repaymentFrequencyType, numberOfRepayments, amortizationMethod, inArrearsTolerance, productCharges, accountingRuleType);
|
||||
}
|
||||
|
||||
protected LoanProduct() {
|
||||
@@ -99,7 +101,8 @@ public class LoanProduct extends AbstractAuditableCustom<AppUser, Long> {
|
||||
final BigDecimal defaultAnnualNominalInterestRate, final InterestMethod interestMethod,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery,
|
||||
final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfInstallments,
|
||||
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance, final Set<Charge> charges) {
|
||||
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance, final Set<Charge> charges,
|
||||
final AccountingRuleType accountingRuleType) {
|
||||
this.fund = fund;
|
||||
this.transactionProcessingStrategy = transactionProcessingStrategy;
|
||||
this.name = name.trim();
|
||||
@@ -115,7 +118,7 @@ public class LoanProduct extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod,
|
||||
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery,
|
||||
repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod, inArrearsTolerance);
|
||||
repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod, inArrearsTolerance, accountingRuleType);
|
||||
}
|
||||
|
||||
public MonetaryCurrency getCurrency() {
|
||||
|
||||
+34
-2
@@ -73,7 +73,23 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
|
||||
@Column(name = "arrearstolerance_amount", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal inArrearsTolerance;
|
||||
|
||||
@Column(name = "accounting_type", nullable = false)
|
||||
private Integer accountingType;
|
||||
|
||||
public static LoanProductRelatedDetail createFrom(final MonetaryCurrency currency, final BigDecimal principal,
|
||||
final BigDecimal nominalInterestRatePerPeriod, final PeriodFrequencyType interestRatePeriodFrequencyType,
|
||||
final BigDecimal nominalAnnualInterestRate, final InterestMethod interestMethod,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repaymentEvery,
|
||||
final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer numberOfRepayments,
|
||||
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance,
|
||||
final AccountingRuleType accountingRuleType) {
|
||||
|
||||
return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentPeriodFrequencyType,
|
||||
numberOfRepayments, amortizationMethod, inArrearsTolerance, accountingRuleType);
|
||||
}
|
||||
|
||||
public static LoanProductRelatedDetail createFrom(final MonetaryCurrency currency, final BigDecimal principal,
|
||||
final BigDecimal nominalInterestRatePerPeriod, final PeriodFrequencyType interestRatePeriodFrequencyType,
|
||||
final BigDecimal nominalAnnualInterestRate, final InterestMethod interestMethod,
|
||||
@@ -83,7 +99,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
|
||||
return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentPeriodFrequencyType,
|
||||
numberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
numberOfRepayments, amortizationMethod, inArrearsTolerance, null);
|
||||
}
|
||||
|
||||
protected LoanProductRelatedDetail() {
|
||||
@@ -95,7 +111,8 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
final BigDecimal defaultAnnualNominalInterestRate, final InterestMethod interestMethod,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery,
|
||||
final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfRepayments,
|
||||
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance) {
|
||||
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance,
|
||||
final AccountingRuleType accountingRuleType) {
|
||||
this.currency = currency;
|
||||
this.principal = defaultPrincipal;
|
||||
this.nominalInterestRatePerPeriod = defaultNominalInterestRatePerPeriod;
|
||||
@@ -112,6 +129,9 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
} else {
|
||||
this.inArrearsTolerance = inArrearsTolerance;
|
||||
}
|
||||
if(accountingRuleType !=null){
|
||||
this.accountingType = accountingRuleType.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
public MonetaryCurrency getCurrency() {
|
||||
@@ -164,6 +184,11 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
public AmortizationMethod getAmortizationMethod() {
|
||||
return amortizationMethod;
|
||||
}
|
||||
|
||||
|
||||
public Integer getAccountingType() {
|
||||
return this.accountingType;
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command, final AprCalculator aprCalculator) {
|
||||
|
||||
@@ -285,6 +310,13 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(newValue);
|
||||
}
|
||||
|
||||
final String accountingTypeParamName = "accountingType";
|
||||
if (command.isChangeInIntegerParameterNamed(accountingTypeParamName, this.accountingType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(accountingTypeParamName);
|
||||
actualChanges.put(accountingTypeParamName, newValue);
|
||||
this.accountingType = newValue;
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
+22
-3
@@ -8,6 +8,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.accounting.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
|
||||
@@ -32,7 +33,10 @@ public final class LoanProductCommandFromApiJsonDeserializer extends AbstractFro
|
||||
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("name", "description", "fundId",
|
||||
"transactionProcessingStrategyId", "currencyCode", "digitsAfterDecimal", "principal", "inArrearsTolerance",
|
||||
"interestRatePerPeriod", "repaymentEvery", "numberOfRepayments", "repaymentFrequencyType", "interestRateFrequencyType",
|
||||
"amortizationType", "interestType", "interestCalculationPeriodType", "charges", "locale"));
|
||||
"amortizationType", "interestType", "interestCalculationPeriodType", "charges", "locale", "accountingType" , LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(),LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(),LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(),LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(),LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue()));
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@@ -71,9 +75,24 @@ public final class LoanProductCommandFromApiJsonDeserializer extends AbstractFro
|
||||
final Integer interestCalculationPeriodType = fromApiJsonHelper.extractIntegerWithLocaleNamed("interestCalculationPeriodType",
|
||||
element);
|
||||
final String[] charges = fromApiJsonHelper.extractArrayNamed("charges", element);
|
||||
|
||||
//extract accounting related fields
|
||||
final Integer accountingType = fromApiJsonHelper.extractIntegerWithLocaleNamed("accountingType",
|
||||
element);
|
||||
final Long loanPortfolioAccountId = fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), element);
|
||||
final Long fundAccountId = fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), element);
|
||||
final Long incomeFromInterestId = fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), element);
|
||||
final Long incomeFromFeeId = fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), element);
|
||||
final Long incomeFromPenaltyId = fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), element);
|
||||
final Long writeOffAccountId = fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), element);
|
||||
final Long receivableInterestAccountId = fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(), element);
|
||||
final Long receivableFeeAccountId = fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), element);
|
||||
final Long receivablePenaltyAccountId = fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(), element);
|
||||
|
||||
return new LoanProductCommand(name, description, fundId, transactionProcessingStrategyId, currencyCode, digitsAfterDecimal,
|
||||
principal, inArrearsTolerance, numberOfRepayments, repaymentEvery, interestRatePerPeriod, repaymentFrequencyType,
|
||||
interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, charges);
|
||||
}
|
||||
interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, charges, accountingType,
|
||||
loanPortfolioAccountId, fundAccountId, incomeFromInterestId, incomeFromFeeId, incomeFromPenaltyId, writeOffAccountId,
|
||||
receivableInterestAccountId, receivableFeeAccountId, receivablePenaltyAccountId);
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -101,7 +101,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
+ "lp.annual_nominal_interest_rate as annualInterestRate, lp.interest_method_enum as interestMethod, lp.interest_calculated_in_period_enum as interestCalculationInPeriodMethod,"
|
||||
+ "lp.repay_every as repaidEvery, lp.repayment_period_frequency_enum as repaymentPeriodFrequency, lp.number_of_repayments as numberOfRepayments, "
|
||||
+ "lp.amortization_method_enum as amortizationMethod, lp.arrearstolerance_amount as tolerance, "
|
||||
+ "lp.created_date as createdon, lp.lastmodified_date as modifiedon, "
|
||||
+ "lp.created_date as createdon, lp.lastmodified_date as modifiedon, lp.accounting_type as accountingType, "
|
||||
+ "curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol "
|
||||
+ " from m_product_loan lp "
|
||||
+ " left join m_fund f on f.id = lp.fund_id"
|
||||
@@ -136,6 +136,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
|
||||
final Integer numberOfRepayments = JdbcSupport.getInteger(rs,"numberOfRepayments");
|
||||
final Integer repaymentEvery = JdbcSupport.getInteger(rs, "repaidEvery");
|
||||
final Integer accountingType = JdbcSupport.getInteger(rs, "accountingType");
|
||||
final Integer loanTermFrequency = repaymentEvery * numberOfRepayments;
|
||||
final BigDecimal interestRatePerPeriod = rs.getBigDecimal("interestRatePerPeriod");
|
||||
final BigDecimal annualInterestRate = rs.getBigDecimal("annualInterestRate");
|
||||
@@ -165,7 +166,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
numberOfRepayments, loanTermFrequency, repaymentEvery, interestRatePerPeriod,
|
||||
annualInterestRate, loanTermFrequencyType, repaymentFrequencyType,
|
||||
interestRateFrequencyType, amortizationType, interestType,
|
||||
interestCalculationPeriodType, fundId, fundName, transactionStrategyId, transactionStrategyName, this.charges);
|
||||
interestCalculationPeriodType, fundId, fundName, transactionStrategyId, transactionStrategyName, this.charges, accountingType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+14
-1
@@ -4,6 +4,7 @@ import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mifosplatform.accounting.service.ProductToGLAccountMappingWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
@@ -40,13 +41,14 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
||||
private final FundRepository fundRepository;
|
||||
private final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository;
|
||||
private final ChargeRepository chargeRepository;
|
||||
private final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public LoanProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
final LoanProductCommandFromApiJsonDeserializer fromApiJsonDeserializer, final LoanProductRepository loanProductRepository,
|
||||
final AprCalculator aprCalculator, final FundRepository fundRepository,
|
||||
final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository,
|
||||
final ChargeRepository chargeRepository) {
|
||||
final ChargeRepository chargeRepository, final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService) {
|
||||
this.context = context;
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
this.loanProductRepository = loanProductRepository;
|
||||
@@ -54,6 +56,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
||||
this.fundRepository = fundRepository;
|
||||
this.loanTransactionProcessingStrategyRepository = loanTransactionProcessingStrategyRepository;
|
||||
this.chargeRepository = chargeRepository;
|
||||
this.accountMappingWritePlatformService = accountMappingWritePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -75,6 +78,9 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
||||
this.aprCalculator);
|
||||
|
||||
this.loanProductRepository.save(loanproduct);
|
||||
|
||||
//save accounting mappings
|
||||
accountMappingWritePlatformService.createLoanProductToGLAccountMapping(loanproduct.getId(), loanProductCommand);
|
||||
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(loanproduct.getId()).build();
|
||||
}
|
||||
@@ -128,6 +134,12 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
||||
final Set<Charge> charges = this.assembleSetOfCharges(command, product.getCurrency().getCode());
|
||||
product.update(charges);
|
||||
}
|
||||
|
||||
// accounting related changes
|
||||
if (loanProductCommand.getAccountingType() != null) {
|
||||
boolean accountingTypeChanged = changes.containsKey("accountingType");
|
||||
accountMappingWritePlatformService.updateLoanProductToGLAccountMapping(product.getId(), loanProductCommand, accountingTypeChanged);
|
||||
}
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
this.loanProductRepository.save(product);
|
||||
@@ -164,4 +176,5 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
||||
|
||||
return charges;
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -140,6 +140,6 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
|
||||
return new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod,
|
||||
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod,
|
||||
interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType, defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType, defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance, null);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user