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;
|
package org.mifosplatform.accounting;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class AccountingConstants {
|
public class AccountingConstants {
|
||||||
|
|
||||||
/*** Categories for Accounting **/
|
/*** 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 java.util.List;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.AccountingConstants;
|
||||||
import org.mifosplatform.accounting.api.data.GLAccountData;
|
import org.mifosplatform.accounting.api.data.GLAccountData;
|
||||||
|
|
||||||
public interface GLAccountReadPlatformService {
|
public interface GLAccountReadPlatformService {
|
||||||
@@ -11,4 +12,6 @@ public interface GLAccountReadPlatformService {
|
|||||||
|
|
||||||
GLAccountData retrieveGLAccountById(long glAccountId);
|
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 java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
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_CLASSIFICATION;
|
||||||
import org.mifosplatform.accounting.AccountingConstants.GL_ACCOUNT_USAGE;
|
import org.mifosplatform.accounting.AccountingConstants.GL_ACCOUNT_USAGE;
|
||||||
import org.mifosplatform.accounting.api.data.GLAccountData;
|
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) {
|
private static boolean checkValidGLAccountClassification(final String entityType) {
|
||||||
for (GL_ACCOUNT_CLASSIFICATION classification : GL_ACCOUNT_CLASSIFICATION.values()) {
|
for (GL_ACCOUNT_CLASSIFICATION classification : GL_ACCOUNT_CLASSIFICATION.values()) {
|
||||||
if (classification.name().toString().equalsIgnoreCase(entityType)) { return true; }
|
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,
|
return new LoanProductRelatedDetail(currency, principalAmount, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
|
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.MediaType;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
|
|
||||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||||
import org.mifosplatform.commands.service.CommandWrapperBuilder;
|
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.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||||
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
@@ -51,7 +59,10 @@ public class LoanProductsApiResource {
|
|||||||
"interestRateFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType", "charges", "createdOn",
|
"interestRateFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType", "charges", "createdOn",
|
||||||
"lastModifedOn", "currencyOptions", "amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions",
|
"lastModifedOn", "currencyOptions", "amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions",
|
||||||
"repaymentFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "fundOptions", "transactionProcessingStrategyOptions",
|
"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";
|
private final String resourceNameForPermissions = "LOANPRODUCT";
|
||||||
|
|
||||||
@@ -64,6 +75,8 @@ public class LoanProductsApiResource {
|
|||||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||||
private final LoanDropdownReadPlatformService dropdownReadPlatformService;
|
private final LoanDropdownReadPlatformService dropdownReadPlatformService;
|
||||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||||
|
private final GLAccountReadPlatformService accountReadPlatformService;
|
||||||
|
private final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanProductsApiResource(final PlatformSecurityContext context, final LoanProductReadPlatformService readPlatformService,
|
public LoanProductsApiResource(final PlatformSecurityContext context, final LoanProductReadPlatformService readPlatformService,
|
||||||
@@ -71,7 +84,9 @@ public class LoanProductsApiResource {
|
|||||||
final FundReadPlatformService fundReadPlatformService, final LoanDropdownReadPlatformService dropdownReadPlatformService,
|
final FundReadPlatformService fundReadPlatformService, final LoanDropdownReadPlatformService dropdownReadPlatformService,
|
||||||
final DefaultToApiJsonSerializer<LoanProductData> toApiJsonSerializer,
|
final DefaultToApiJsonSerializer<LoanProductData> toApiJsonSerializer,
|
||||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||||
|
final GLAccountReadPlatformService accountReadPlatformService,
|
||||||
|
final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.loanProductReadPlatformService = readPlatformService;
|
this.loanProductReadPlatformService = readPlatformService;
|
||||||
this.chargeReadPlatformService = chargeReadPlatformService;
|
this.chargeReadPlatformService = chargeReadPlatformService;
|
||||||
@@ -81,6 +96,8 @@ public class LoanProductsApiResource {
|
|||||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||||
|
this.accountReadPlatformService = accountReadPlatformService;
|
||||||
|
this.accountMappingReadPlatformService = accountMappingReadPlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@@ -137,8 +154,10 @@ public class LoanProductsApiResource {
|
|||||||
if (settings.isTemplate()) {
|
if (settings.isTemplate()) {
|
||||||
loanProduct = handleTemplate(loanProduct);
|
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
|
@PUT
|
||||||
@@ -174,9 +193,14 @@ public class LoanProductsApiResource {
|
|||||||
final Collection<FundData> fundOptions = this.fundReadPlatformService.retrieveAllFunds();
|
final Collection<FundData> fundOptions = this.fundReadPlatformService.retrieveAllFunds();
|
||||||
final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions = this.dropdownReadPlatformService
|
final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions = this.dropdownReadPlatformService
|
||||||
.retreiveTransactionProcessingStrategies();
|
.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,
|
return new LoanProductData(productData, chargeOptions, currencyOptions, amortizationTypeOptions, interestTypeOptions,
|
||||||
interestCalculationPeriodTypeOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions,
|
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.ArrayList;
|
||||||
import java.util.List;
|
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.ApiParameterError;
|
||||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
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.
|
* Immutable command for creating or updating details of a loan product.
|
||||||
@@ -31,11 +33,28 @@ public class LoanProductCommand {
|
|||||||
private final Integer interestCalculationPeriodType;
|
private final Integer interestCalculationPeriodType;
|
||||||
private final String[] charges;
|
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,
|
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 String currencyCode, final Integer digitsAfterDecimal, final BigDecimal principal, final BigDecimal inArrearsTolerance,
|
||||||
final Integer numberOfRepayments, final Integer repaymentEvery, final BigDecimal interestRatePerPeriod,
|
final Integer numberOfRepayments, final Integer repaymentEvery, final BigDecimal interestRatePerPeriod,
|
||||||
final Integer repaymentFrequencyType, final Integer interestRateFrequencyType, final Integer amortizationType,
|
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.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.fundId = fundId;
|
this.fundId = fundId;
|
||||||
@@ -57,6 +76,18 @@ public class LoanProductCommand {
|
|||||||
this.interestType = interestType;
|
this.interestType = interestType;
|
||||||
this.interestCalculationPeriodType = interestCalculationPeriodType;
|
this.interestCalculationPeriodType = interestCalculationPeriodType;
|
||||||
this.charges = charges;
|
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() {
|
public String getName() {
|
||||||
@@ -127,6 +158,55 @@ public class LoanProductCommand {
|
|||||||
return charges;
|
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() {
|
public void validateForCreate() {
|
||||||
|
|
||||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
@@ -154,6 +234,38 @@ public class LoanProductCommand {
|
|||||||
baseDataValidator.reset().parameter("interestCalculationPeriodType").value(this.interestCalculationPeriodType).notNull()
|
baseDataValidator.reset().parameter("interestCalculationPeriodType").value(this.interestCalculationPeriodType).notNull()
|
||||||
.inMinMaxRange(0, 1);
|
.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",
|
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||||
"Validation errors exist.", dataValidationErrors); }
|
"Validation errors exist.", dataValidationErrors); }
|
||||||
}
|
}
|
||||||
@@ -182,20 +294,50 @@ public class LoanProductCommand {
|
|||||||
.integerGreaterThanZero();
|
.integerGreaterThanZero();
|
||||||
|
|
||||||
baseDataValidator.reset().parameter("interestRatePerPeriod").value(this.interestRatePerPeriod).ignoreIfNull().notBlank();
|
baseDataValidator.reset().parameter("interestRatePerPeriod").value(this.interestRatePerPeriod).ignoreIfNull().notBlank();
|
||||||
baseDataValidator.reset().parameter("interestRateFrequencyType").value(this.interestRateFrequencyType).ignoreIfNull()
|
baseDataValidator.reset().parameter("interestRateFrequencyType").value(this.interestRateFrequencyType).ignoreIfNull().notNull()
|
||||||
.notNull().inMinMaxRange(0, 3);
|
.inMinMaxRange(0, 3);
|
||||||
|
|
||||||
baseDataValidator.reset().parameter("amortizationType").value(this.amortizationType).ignoreIfNull().notNull()
|
baseDataValidator.reset().parameter("amortizationType").value(this.amortizationType).ignoreIfNull().notNull().inMinMaxRange(0, 1);
|
||||||
.inMinMaxRange(0, 1);
|
|
||||||
baseDataValidator.reset().parameter("interestType").value(this.interestType).ignoreIfNull().notNull().inMinMaxRange(0, 1);
|
baseDataValidator.reset().parameter("interestType").value(this.interestType).ignoreIfNull().notNull().inMinMaxRange(0, 1);
|
||||||
baseDataValidator.reset().parameter("interestCalculationPeriodType").value(this.interestCalculationPeriodType)
|
baseDataValidator.reset().parameter("interestCalculationPeriodType").value(this.interestCalculationPeriodType).ignoreIfNull()
|
||||||
.ignoreIfNull().notNull().inMinMaxRange(0, 1);
|
.notNull().inMinMaxRange(0, 1);
|
||||||
|
|
||||||
baseDataValidator.reset().anyOfNotNull(this.fundId, this.transactionProcessingStrategyId, this.name,
|
// validation for accounting rules
|
||||||
this.description, this.currencyCode, this.digitsAfterDecimal, this.principal,
|
baseDataValidator.reset().parameter("accountingType").value(this.accountingType).ignoreIfNull().inMinMaxRange(1, 3);
|
||||||
this.inArrearsTolerance, this.repaymentFrequencyType, this.repaymentEvery,
|
if (this.getAccountingType() != null) {
|
||||||
this.numberOfRepayments, this.interestRatePerPeriod, this.interestRateFrequencyType,
|
/**
|
||||||
this.amortizationType, this.interestType, this.interestCalculationPeriodType, this.charges);
|
* 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",
|
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||||
"Validation errors exist.", dataValidationErrors); }
|
"Validation errors exist.", dataValidationErrors); }
|
||||||
|
|||||||
+144
-4
@@ -6,6 +6,7 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
import org.mifosplatform.accounting.api.data.GLAccountData;
|
||||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||||
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||||
@@ -40,6 +41,7 @@ public class LoanProductData {
|
|||||||
private final Integer repaymentEvery;
|
private final Integer repaymentEvery;
|
||||||
private final BigDecimal interestRatePerPeriod;
|
private final BigDecimal interestRatePerPeriod;
|
||||||
private final BigDecimal annualInterestRate;
|
private final BigDecimal annualInterestRate;
|
||||||
|
private final Integer accountingType;
|
||||||
|
|
||||||
private final EnumOptionData loanTermFrequencyType;
|
private final EnumOptionData loanTermFrequencyType;
|
||||||
private final EnumOptionData repaymentFrequencyType;
|
private final EnumOptionData repaymentFrequencyType;
|
||||||
@@ -64,6 +66,23 @@ public class LoanProductData {
|
|||||||
private final List<EnumOptionData> loanTermFrequencyTypeOptions;
|
private final List<EnumOptionData> loanTermFrequencyTypeOptions;
|
||||||
private final Collection<ChargeData> chargeOptions;
|
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.
|
* Used when returning lookup information about loan product for dropdowns.
|
||||||
*/
|
*/
|
||||||
@@ -90,11 +109,12 @@ public class LoanProductData {
|
|||||||
final Long transactionProcessingStrategyId = null;
|
final Long transactionProcessingStrategyId = null;
|
||||||
final String transactionProcessingStrategyName = null;
|
final String transactionProcessingStrategyName = null;
|
||||||
final Collection<ChargeData> charges = null;
|
final Collection<ChargeData> charges = null;
|
||||||
|
final Integer accountingType = null;
|
||||||
|
|
||||||
return new LoanProductData(createdOn, lastModifedOn, id, name, description, currency, principal, tolerance, numberOfRepayments,
|
return new LoanProductData(createdOn, lastModifedOn, id, name, description, currency, principal, tolerance, numberOfRepayments,
|
||||||
loanTermFrequency, repaymentEvery, interestRatePerPeriod, annualInterestRate, loanTermFrequencyType,
|
loanTermFrequency, repaymentEvery, interestRatePerPeriod, annualInterestRate, loanTermFrequencyType,
|
||||||
repaymentFrequencyType, interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, fundId,
|
repaymentFrequencyType, interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, fundId,
|
||||||
fundName, transactionProcessingStrategyId, transactionProcessingStrategyName, charges);
|
fundName, transactionProcessingStrategyId, transactionProcessingStrategyName, charges, accountingType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanProductData sensibleDefaultsForNewLoanProductCreation() {
|
public static LoanProductData sensibleDefaultsForNewLoanProductCreation() {
|
||||||
@@ -124,11 +144,12 @@ public class LoanProductData {
|
|||||||
final Long transactionProcessingStrategyId = null;
|
final Long transactionProcessingStrategyId = null;
|
||||||
final String transactionProcessingStrategyName = null;
|
final String transactionProcessingStrategyName = null;
|
||||||
final Collection<ChargeData> charges = null;
|
final Collection<ChargeData> charges = null;
|
||||||
|
final Integer accountingType = 1;
|
||||||
|
|
||||||
return new LoanProductData(createdOn, lastModifedOn, id, name, description, currency, principal, tolerance, numberOfRepayments,
|
return new LoanProductData(createdOn, lastModifedOn, id, name, description, currency, principal, tolerance, numberOfRepayments,
|
||||||
loanTermFrequency, repaymentEvery, interestRatePerPeriod, annualInterestRate, loanTermFrequencyType,
|
loanTermFrequency, repaymentEvery, interestRatePerPeriod, annualInterestRate, loanTermFrequencyType,
|
||||||
repaymentFrequencyType, interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, fundId,
|
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,
|
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 repaymentFrequencyType, final EnumOptionData interestRateFrequencyType,
|
||||||
final EnumOptionData amortizationType, final EnumOptionData interestType, final EnumOptionData interestCalculationPeriodType,
|
final EnumOptionData amortizationType, final EnumOptionData interestType, final EnumOptionData interestCalculationPeriodType,
|
||||||
final Long fundId, final String fundName, final Long transactionProcessingStrategyId,
|
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.createdOn = createdOn;
|
||||||
this.lastModifedOn = lastModifedOn;
|
this.lastModifedOn = lastModifedOn;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@@ -163,6 +184,7 @@ public class LoanProductData {
|
|||||||
this.transactionProcessingStrategyId = transactionProcessingStrategyId;
|
this.transactionProcessingStrategyId = transactionProcessingStrategyId;
|
||||||
this.transactionProcessingStrategyName = transactionProcessingStrategyName;
|
this.transactionProcessingStrategyName = transactionProcessingStrategyName;
|
||||||
this.charges = charges;
|
this.charges = charges;
|
||||||
|
this.accountingType = accountingType;
|
||||||
|
|
||||||
this.chargeOptions = null;
|
this.chargeOptions = null;
|
||||||
this.currencyOptions = null;
|
this.currencyOptions = null;
|
||||||
@@ -174,6 +196,10 @@ public class LoanProductData {
|
|||||||
this.loanTermFrequencyTypeOptions = null;
|
this.loanTermFrequencyTypeOptions = null;
|
||||||
this.repaymentFrequencyTypeOptions = null;
|
this.repaymentFrequencyTypeOptions = null;
|
||||||
this.interestRateFrequencyTypeOptions = null;
|
this.interestRateFrequencyTypeOptions = null;
|
||||||
|
|
||||||
|
this.assetAccountOptions = null;
|
||||||
|
this.incomeAccountOptions = null;
|
||||||
|
this.expenseAccountOptions = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoanProductData(final LoanProductData productData, final Collection<ChargeData> chargeOptions,
|
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> interestTypeOptions, final List<EnumOptionData> interestCalculationPeriodTypeOptions,
|
||||||
final List<EnumOptionData> loanTermFrequencyTypeOptions, final List<EnumOptionData> repaymentFrequencyTypeOptions,
|
final List<EnumOptionData> loanTermFrequencyTypeOptions, final List<EnumOptionData> repaymentFrequencyTypeOptions,
|
||||||
final List<EnumOptionData> interestRateFrequencyTypeOptions, final Collection<FundData> fundOptions,
|
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.createdOn = productData.createdOn;
|
||||||
this.lastModifedOn = productData.lastModifedOn;
|
this.lastModifedOn = productData.lastModifedOn;
|
||||||
this.id = productData.id;
|
this.id = productData.id;
|
||||||
@@ -205,6 +233,7 @@ public class LoanProductData {
|
|||||||
this.transactionProcessingStrategyId = productData.transactionProcessingStrategyId;
|
this.transactionProcessingStrategyId = productData.transactionProcessingStrategyId;
|
||||||
this.transactionProcessingStrategyName = productData.transactionProcessingStrategyName;
|
this.transactionProcessingStrategyName = productData.transactionProcessingStrategyName;
|
||||||
this.charges = productData.charges();
|
this.charges = productData.charges();
|
||||||
|
this.accountingType = productData.accountingType;
|
||||||
|
|
||||||
this.chargeOptions = chargeOptions;
|
this.chargeOptions = chargeOptions;
|
||||||
this.currencyOptions = currencyOptions;
|
this.currencyOptions = currencyOptions;
|
||||||
@@ -221,6 +250,10 @@ public class LoanProductData {
|
|||||||
this.loanTermFrequencyTypeOptions = loanTermFrequencyTypeOptions;
|
this.loanTermFrequencyTypeOptions = loanTermFrequencyTypeOptions;
|
||||||
this.repaymentFrequencyTypeOptions = repaymentFrequencyTypeOptions;
|
this.repaymentFrequencyTypeOptions = repaymentFrequencyTypeOptions;
|
||||||
this.interestRateFrequencyTypeOptions = interestRateFrequencyTypeOptions;
|
this.interestRateFrequencyTypeOptions = interestRateFrequencyTypeOptions;
|
||||||
|
|
||||||
|
this.assetAccountOptions = assetAccountOptions;
|
||||||
|
this.incomeAccountOptions = incomeAccountOptions;
|
||||||
|
this.expenseAccountOptions = expenseAccountOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<ChargeData> charges() {
|
public Collection<ChargeData> charges() {
|
||||||
@@ -362,4 +395,111 @@ public class LoanProductData {
|
|||||||
public Collection<ChargeData> getChargeOptions() {
|
public Collection<ChargeData> getChargeOptions() {
|
||||||
return chargeOptions;
|
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 repaymentEvery = command.integerValueOfParameterNamed("repaymentEvery");
|
||||||
final Integer numberOfRepayments = command.integerValueOfParameterNamed("numberOfRepayments");
|
final Integer numberOfRepayments = command.integerValueOfParameterNamed("numberOfRepayments");
|
||||||
final BigDecimal inArrearsTolerance = command.bigDecimalValueOfParameterNamed("inArrearsTolerance");
|
final BigDecimal inArrearsTolerance = command.bigDecimalValueOfParameterNamed("inArrearsTolerance");
|
||||||
|
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(command
|
||||||
|
.integerValueOfParameterNamed("accountingType"));
|
||||||
|
|
||||||
return new LoanProduct(fund, loanTransactionProcessingStrategy, name, description, currency, principal, interestRatePerPeriod,
|
return new LoanProduct(fund, loanTransactionProcessingStrategy, name, description, currency, principal, interestRatePerPeriod,
|
||||||
interestFrequencyType, annualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery,
|
interestFrequencyType, annualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery,
|
||||||
repaymentFrequencyType, numberOfRepayments, amortizationMethod, inArrearsTolerance, productCharges);
|
repaymentFrequencyType, numberOfRepayments, amortizationMethod, inArrearsTolerance, productCharges, accountingRuleType);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected LoanProduct() {
|
protected LoanProduct() {
|
||||||
@@ -99,7 +101,8 @@ public class LoanProduct extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
final BigDecimal defaultAnnualNominalInterestRate, final InterestMethod interestMethod,
|
final BigDecimal defaultAnnualNominalInterestRate, final InterestMethod interestMethod,
|
||||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery,
|
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery,
|
||||||
final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfInstallments,
|
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.fund = fund;
|
||||||
this.transactionProcessingStrategy = transactionProcessingStrategy;
|
this.transactionProcessingStrategy = transactionProcessingStrategy;
|
||||||
this.name = name.trim();
|
this.name = name.trim();
|
||||||
@@ -115,7 +118,7 @@ public class LoanProduct extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
|
|
||||||
this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod,
|
this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod,
|
||||||
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery,
|
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery,
|
||||||
repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod, inArrearsTolerance);
|
repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod, inArrearsTolerance, accountingRuleType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonetaryCurrency getCurrency() {
|
public MonetaryCurrency getCurrency() {
|
||||||
|
|||||||
+34
-2
@@ -73,7 +73,23 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
|||||||
|
|
||||||
@Column(name = "arrearstolerance_amount", scale = 6, precision = 19, nullable = true)
|
@Column(name = "arrearstolerance_amount", scale = 6, precision = 19, nullable = true)
|
||||||
private BigDecimal inArrearsTolerance;
|
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,
|
public static LoanProductRelatedDetail createFrom(final MonetaryCurrency currency, final BigDecimal principal,
|
||||||
final BigDecimal nominalInterestRatePerPeriod, final PeriodFrequencyType interestRatePeriodFrequencyType,
|
final BigDecimal nominalInterestRatePerPeriod, final PeriodFrequencyType interestRatePeriodFrequencyType,
|
||||||
final BigDecimal nominalAnnualInterestRate, final InterestMethod interestMethod,
|
final BigDecimal nominalAnnualInterestRate, final InterestMethod interestMethod,
|
||||||
@@ -83,7 +99,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
|||||||
|
|
||||||
return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||||
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentPeriodFrequencyType,
|
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentPeriodFrequencyType,
|
||||||
numberOfRepayments, amortizationMethod, inArrearsTolerance);
|
numberOfRepayments, amortizationMethod, inArrearsTolerance, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected LoanProductRelatedDetail() {
|
protected LoanProductRelatedDetail() {
|
||||||
@@ -95,7 +111,8 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
|||||||
final BigDecimal defaultAnnualNominalInterestRate, final InterestMethod interestMethod,
|
final BigDecimal defaultAnnualNominalInterestRate, final InterestMethod interestMethod,
|
||||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery,
|
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery,
|
||||||
final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfRepayments,
|
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.currency = currency;
|
||||||
this.principal = defaultPrincipal;
|
this.principal = defaultPrincipal;
|
||||||
this.nominalInterestRatePerPeriod = defaultNominalInterestRatePerPeriod;
|
this.nominalInterestRatePerPeriod = defaultNominalInterestRatePerPeriod;
|
||||||
@@ -112,6 +129,9 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
|||||||
} else {
|
} else {
|
||||||
this.inArrearsTolerance = inArrearsTolerance;
|
this.inArrearsTolerance = inArrearsTolerance;
|
||||||
}
|
}
|
||||||
|
if(accountingRuleType !=null){
|
||||||
|
this.accountingType = accountingRuleType.getValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonetaryCurrency getCurrency() {
|
public MonetaryCurrency getCurrency() {
|
||||||
@@ -164,6 +184,11 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
|||||||
public AmortizationMethod getAmortizationMethod() {
|
public AmortizationMethod getAmortizationMethod() {
|
||||||
return amortizationMethod;
|
return amortizationMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Integer getAccountingType() {
|
||||||
|
return this.accountingType;
|
||||||
|
}
|
||||||
|
|
||||||
public Map<String, Object> update(final JsonCommand command, final AprCalculator aprCalculator) {
|
public Map<String, Object> update(final JsonCommand command, final AprCalculator aprCalculator) {
|
||||||
|
|
||||||
@@ -285,6 +310,13 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
|||||||
actualChanges.put("locale", localeAsInput);
|
actualChanges.put("locale", localeAsInput);
|
||||||
this.interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(newValue);
|
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;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-3
@@ -8,6 +8,7 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
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.exception.InvalidJsonException;
|
||||||
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
|
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
|
||||||
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
|
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",
|
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("name", "description", "fundId",
|
||||||
"transactionProcessingStrategyId", "currencyCode", "digitsAfterDecimal", "principal", "inArrearsTolerance",
|
"transactionProcessingStrategyId", "currencyCode", "digitsAfterDecimal", "principal", "inArrearsTolerance",
|
||||||
"interestRatePerPeriod", "repaymentEvery", "numberOfRepayments", "repaymentFrequencyType", "interestRateFrequencyType",
|
"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;
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
|
||||||
@@ -71,9 +75,24 @@ public final class LoanProductCommandFromApiJsonDeserializer extends AbstractFro
|
|||||||
final Integer interestCalculationPeriodType = fromApiJsonHelper.extractIntegerWithLocaleNamed("interestCalculationPeriodType",
|
final Integer interestCalculationPeriodType = fromApiJsonHelper.extractIntegerWithLocaleNamed("interestCalculationPeriodType",
|
||||||
element);
|
element);
|
||||||
final String[] charges = fromApiJsonHelper.extractArrayNamed("charges", 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,
|
return new LoanProductCommand(name, description, fundId, transactionProcessingStrategyId, currencyCode, digitsAfterDecimal,
|
||||||
principal, inArrearsTolerance, numberOfRepayments, repaymentEvery, interestRatePerPeriod, repaymentFrequencyType,
|
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.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.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.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 "
|
+ "curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol "
|
||||||
+ " from m_product_loan lp "
|
+ " from m_product_loan lp "
|
||||||
+ " left join m_fund f on f.id = lp.fund_id"
|
+ " 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 numberOfRepayments = JdbcSupport.getInteger(rs,"numberOfRepayments");
|
||||||
final Integer repaymentEvery = JdbcSupport.getInteger(rs, "repaidEvery");
|
final Integer repaymentEvery = JdbcSupport.getInteger(rs, "repaidEvery");
|
||||||
|
final Integer accountingType = JdbcSupport.getInteger(rs, "accountingType");
|
||||||
final Integer loanTermFrequency = repaymentEvery * numberOfRepayments;
|
final Integer loanTermFrequency = repaymentEvery * numberOfRepayments;
|
||||||
final BigDecimal interestRatePerPeriod = rs.getBigDecimal("interestRatePerPeriod");
|
final BigDecimal interestRatePerPeriod = rs.getBigDecimal("interestRatePerPeriod");
|
||||||
final BigDecimal annualInterestRate = rs.getBigDecimal("annualInterestRate");
|
final BigDecimal annualInterestRate = rs.getBigDecimal("annualInterestRate");
|
||||||
@@ -165,7 +166,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
numberOfRepayments, loanTermFrequency, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, loanTermFrequency, repaymentEvery, interestRatePerPeriod,
|
||||||
annualInterestRate, loanTermFrequencyType, repaymentFrequencyType,
|
annualInterestRate, loanTermFrequencyType, repaymentFrequencyType,
|
||||||
interestRateFrequencyType, amortizationType, interestType,
|
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.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.service.ProductToGLAccountMappingWritePlatformService;
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||||
@@ -40,13 +41,14 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
private final FundRepository fundRepository;
|
private final FundRepository fundRepository;
|
||||||
private final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository;
|
private final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository;
|
||||||
private final ChargeRepository chargeRepository;
|
private final ChargeRepository chargeRepository;
|
||||||
|
private final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
public LoanProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||||
final LoanProductCommandFromApiJsonDeserializer fromApiJsonDeserializer, final LoanProductRepository loanProductRepository,
|
final LoanProductCommandFromApiJsonDeserializer fromApiJsonDeserializer, final LoanProductRepository loanProductRepository,
|
||||||
final AprCalculator aprCalculator, final FundRepository fundRepository,
|
final AprCalculator aprCalculator, final FundRepository fundRepository,
|
||||||
final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository,
|
final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository,
|
||||||
final ChargeRepository chargeRepository) {
|
final ChargeRepository chargeRepository, final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||||
this.loanProductRepository = loanProductRepository;
|
this.loanProductRepository = loanProductRepository;
|
||||||
@@ -54,6 +56,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
this.fundRepository = fundRepository;
|
this.fundRepository = fundRepository;
|
||||||
this.loanTransactionProcessingStrategyRepository = loanTransactionProcessingStrategyRepository;
|
this.loanTransactionProcessingStrategyRepository = loanTransactionProcessingStrategyRepository;
|
||||||
this.chargeRepository = chargeRepository;
|
this.chargeRepository = chargeRepository;
|
||||||
|
this.accountMappingWritePlatformService = accountMappingWritePlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -75,6 +78,9 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
this.aprCalculator);
|
this.aprCalculator);
|
||||||
|
|
||||||
this.loanProductRepository.save(loanproduct);
|
this.loanProductRepository.save(loanproduct);
|
||||||
|
|
||||||
|
//save accounting mappings
|
||||||
|
accountMappingWritePlatformService.createLoanProductToGLAccountMapping(loanproduct.getId(), loanProductCommand);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(loanproduct.getId()).build();
|
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());
|
final Set<Charge> charges = this.assembleSetOfCharges(command, product.getCurrency().getCode());
|
||||||
product.update(charges);
|
product.update(charges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// accounting related changes
|
||||||
|
if (loanProductCommand.getAccountingType() != null) {
|
||||||
|
boolean accountingTypeChanged = changes.containsKey("accountingType");
|
||||||
|
accountMappingWritePlatformService.updateLoanProductToGLAccountMapping(product.getId(), loanProductCommand, accountingTypeChanged);
|
||||||
|
}
|
||||||
|
|
||||||
if (!changes.isEmpty()) {
|
if (!changes.isEmpty()) {
|
||||||
this.loanProductRepository.save(product);
|
this.loanProductRepository.save(product);
|
||||||
@@ -164,4 +176,5 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
|
|
||||||
return charges;
|
return charges;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -140,6 +140,6 @@ public class LoanProductRelatedDetailTestHelper {
|
|||||||
|
|
||||||
return new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod,
|
return new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod,
|
||||||
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod,
|
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod,
|
||||||
interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType, defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
|
interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType, defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user