Merge pull request #308 from vishwasbabu/mifosx-345
accounting integration for savings and refactoring
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
/*add accounting type field to savings product*/
|
||||||
|
ALTER TABLE `m_savings_product`
|
||||||
|
ADD COLUMN `accounting_type` SMALLINT(5) NOT NULL AFTER `lockin_period_frequency_enum`;
|
||||||
|
|
||||||
|
/*update existing savings products to have "No" accounting*/
|
||||||
|
update m_savings_product set accounting_type=1;
|
||||||
|
|
||||||
|
/*track payment details for savings transactions*/
|
||||||
|
ALTER TABLE `m_savings_account_transaction`
|
||||||
|
ADD COLUMN `payment_detail_id` BIGINT(20) NULL DEFAULT NULL AFTER `savings_account_id`,
|
||||||
|
ADD CONSTRAINT `FK_m_savings_account_transaction_m_payment_detail` FOREIGN KEY (`payment_detail_id`) REFERENCES `m_payment_detail` (`id`);
|
||||||
|
|
||||||
+57
@@ -103,6 +103,63 @@ public class AccountingConstants {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** Accounting placeholders for cash based accounting for loan products ***/
|
||||||
|
public static enum CASH_ACCOUNTS_FOR_SAVINGS {
|
||||||
|
SAVINGS_REFERENCE(1), SAVINGS_CONTROL(2), INTEREST_ON_SAVINGS(3), INCOME_FROM_FEES(4);
|
||||||
|
|
||||||
|
private final Integer value;
|
||||||
|
|
||||||
|
private CASH_ACCOUNTS_FOR_SAVINGS(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_SAVINGS> intToEnumMap = new HashMap<Integer, CASH_ACCOUNTS_FOR_SAVINGS>();
|
||||||
|
static {
|
||||||
|
for (final CASH_ACCOUNTS_FOR_SAVINGS type : CASH_ACCOUNTS_FOR_SAVINGS.values()) {
|
||||||
|
intToEnumMap.put(type.value, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CASH_ACCOUNTS_FOR_SAVINGS fromInt(final int i) {
|
||||||
|
final CASH_ACCOUNTS_FOR_SAVINGS type = intToEnumMap.get(Integer.valueOf(i));
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Enum of all accounting related input parameter names used while
|
||||||
|
* creating/updating a savings product
|
||||||
|
***/
|
||||||
|
public static enum SAVINGS_PRODUCT_ACCOUNTING_PARAMS {
|
||||||
|
SAVINGS_REFERENCE("savingsReferenceAccountId"), SAVINGS_CONTROL("savingsControlAccountId"), INCOME_FROM_FEES(
|
||||||
|
"incomeFromFeeAccountId"), INTEREST_ON_SAVINGS("interestOnSavingsAccountId"), PAYMENT_CHANNEL_FUND_SOURCE_MAPPING(
|
||||||
|
"paymentChannelToFundSourceMappings"), PAYMENT_TYPE("paymentTypeId"), FUND_SOURCE("fundSourceAccountId");
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
private SAVINGS_PRODUCT_ACCOUNTING_PARAMS(final String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name().toString().replaceAll("_", " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final String ASSESTS_TAG_OPTION_CODE_NAME = "AssetAccountTags";
|
public static final String ASSESTS_TAG_OPTION_CODE_NAME = "AssetAccountTags";
|
||||||
public static final String LIABILITIES_TAG_OPTION_CODE_NAME = "LiabilityAccountTags";
|
public static final String LIABILITIES_TAG_OPTION_CODE_NAME = "LiabilityAccountTags";
|
||||||
public static final String EQUITY_TAG_OPTION_CODE_NAME = "EquityAccountTags";
|
public static final String EQUITY_TAG_OPTION_CODE_NAME = "EquityAccountTags";
|
||||||
|
|||||||
+9
@@ -6,7 +6,9 @@
|
|||||||
package org.mifosplatform.accounting.common;
|
package org.mifosplatform.accounting.common;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
|
|
||||||
public interface AccountingDropdownReadPlatformService {
|
public interface AccountingDropdownReadPlatformService {
|
||||||
@@ -16,4 +18,11 @@ public interface AccountingDropdownReadPlatformService {
|
|||||||
public List<EnumOptionData> retrieveGLAccountUsageOptions();
|
public List<EnumOptionData> retrieveGLAccountUsageOptions();
|
||||||
|
|
||||||
public List<EnumOptionData> retrieveJournalEntryTypeOptions();
|
public List<EnumOptionData> retrieveJournalEntryTypeOptions();
|
||||||
|
|
||||||
|
public List<EnumOptionData> retrieveAccountingRuleTypeOptions();
|
||||||
|
|
||||||
|
public Map<String, List<GLAccountData>> retrieveAccountMappingOptionsForLoanProducts();
|
||||||
|
|
||||||
|
public Map<String, List<GLAccountData>> retrieveAccountMappingOptionsForSavingsProducts();
|
||||||
|
|
||||||
}
|
}
|
||||||
+52
@@ -5,17 +5,29 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.accounting.common;
|
package org.mifosplatform.accounting.common;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountUsage;
|
import org.mifosplatform.accounting.glaccount.domain.GLAccountUsage;
|
||||||
|
import org.mifosplatform.accounting.glaccount.service.GLAccountReadPlatformService;
|
||||||
import org.mifosplatform.accounting.journalentry.domain.JournalEntryType;
|
import org.mifosplatform.accounting.journalentry.domain.JournalEntryType;
|
||||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class AccountingDropdownReadPlatformServiceImpl implements AccountingDropdownReadPlatformService {
|
public class AccountingDropdownReadPlatformServiceImpl implements AccountingDropdownReadPlatformService {
|
||||||
|
|
||||||
|
private final GLAccountReadPlatformService accountReadPlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AccountingDropdownReadPlatformServiceImpl(final GLAccountReadPlatformService accountReadPlatformService) {
|
||||||
|
this.accountReadPlatformService = accountReadPlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<EnumOptionData> retrieveGLAccountTypeOptions() {
|
public List<EnumOptionData> retrieveGLAccountTypeOptions() {
|
||||||
return AccountingEnumerations.gLAccountType(GLAccountType.values());
|
return AccountingEnumerations.gLAccountType(GLAccountType.values());
|
||||||
@@ -31,4 +43,44 @@ public class AccountingDropdownReadPlatformServiceImpl implements AccountingDrop
|
|||||||
return AccountingEnumerations.journalEntryTypes(JournalEntryType.values());
|
return AccountingEnumerations.journalEntryTypes(JournalEntryType.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EnumOptionData> retrieveAccountingRuleTypeOptions() {
|
||||||
|
return AccountingEnumerations.accountingRuleTypes(AccountingRuleType.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, List<GLAccountData>> retrieveAccountMappingOptionsForLoanProducts() {
|
||||||
|
Map<String, List<GLAccountData>> accountOptions = new HashMap<String, List<GLAccountData>>();
|
||||||
|
List<GLAccountData> assetAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GLAccountType.ASSET);
|
||||||
|
if (assetAccountOptions.isEmpty()) {
|
||||||
|
assetAccountOptions = null;
|
||||||
|
}
|
||||||
|
accountOptions.put("assetAccountOptions", assetAccountOptions);
|
||||||
|
|
||||||
|
List<GLAccountData> incomeAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GLAccountType.INCOME);
|
||||||
|
if (incomeAccountOptions.isEmpty()) {
|
||||||
|
incomeAccountOptions = null;
|
||||||
|
}
|
||||||
|
accountOptions.put("incomeAccountOptions", incomeAccountOptions);
|
||||||
|
|
||||||
|
List<GLAccountData> expenseAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GLAccountType.EXPENSE);
|
||||||
|
if (expenseAccountOptions.isEmpty()) {
|
||||||
|
expenseAccountOptions = null;
|
||||||
|
}
|
||||||
|
accountOptions.put("expenseAccountOptions", expenseAccountOptions);
|
||||||
|
return accountOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, List<GLAccountData>> retrieveAccountMappingOptionsForSavingsProducts() {
|
||||||
|
Map<String, List<GLAccountData>> accountOptions = retrieveAccountMappingOptionsForLoanProducts();
|
||||||
|
List<GLAccountData> liabilityAccountOptions = accountReadPlatformService
|
||||||
|
.retrieveAllEnabledDetailGLAccounts(GLAccountType.LIABILITY);
|
||||||
|
if (liabilityAccountOptions.isEmpty()) {
|
||||||
|
liabilityAccountOptions = null;
|
||||||
|
}
|
||||||
|
accountOptions.put("liabilityAccountOptions", liabilityAccountOptions);
|
||||||
|
return accountOptions;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+17
@@ -80,4 +80,21 @@ public class AccountingEnumerations {
|
|||||||
return optionData;
|
return optionData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static EnumOptionData accountingRuleType(final int id) {
|
||||||
|
return accountingRuleType(AccountingRuleType.fromInt(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EnumOptionData accountingRuleType(final AccountingRuleType type) {
|
||||||
|
EnumOptionData optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), type.toString());
|
||||||
|
return optionData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<EnumOptionData> accountingRuleTypes(final AccountingRuleType[] accountingRuleTypes) {
|
||||||
|
final List<EnumOptionData> optionDatas = new ArrayList<EnumOptionData>();
|
||||||
|
for (final AccountingRuleType accountingRuleType : accountingRuleTypes) {
|
||||||
|
optionDatas.add(accountingRuleType(accountingRuleType));
|
||||||
|
}
|
||||||
|
return optionDatas;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.loanproduct.domain;
|
package org.mifosplatform.accounting.common;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
+18
-17
@@ -30,10 +30,10 @@ import org.springframework.data.jpa.domain.AbstractPersistable;
|
|||||||
@Table(name = "acc_gl_account", uniqueConstraints = { @UniqueConstraint(columnNames = { "gl_code" }, name = "acc_gl_code") })
|
@Table(name = "acc_gl_account", uniqueConstraints = { @UniqueConstraint(columnNames = { "gl_code" }, name = "acc_gl_code") })
|
||||||
public class GLAccount extends AbstractPersistable<Long> {
|
public class GLAccount extends AbstractPersistable<Long> {
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "parent_id")
|
@JoinColumn(name = "parent_id")
|
||||||
private GLAccount parent;
|
private GLAccount parent;
|
||||||
|
|
||||||
@Column(name = "hierarchy", nullable = true, length = 50)
|
@Column(name = "hierarchy", nullable = true, length = 50)
|
||||||
private String hierarchy;
|
private String hierarchy;
|
||||||
|
|
||||||
@@ -61,8 +61,8 @@ public class GLAccount extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
@Column(name = "description", nullable = true, length = 500)
|
@Column(name = "description", nullable = true, length = 500)
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "tag_id")
|
@JoinColumn(name = "tag_id")
|
||||||
private CodeValue tagId;
|
private CodeValue tagId;
|
||||||
|
|
||||||
@@ -105,7 +105,8 @@ public class GLAccount extends AbstractPersistable<Long> {
|
|||||||
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.PARENT_ID.getValue(), 0L);
|
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.PARENT_ID.getValue(), 0L);
|
||||||
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.TYPE.getValue(), this.type, true);
|
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.TYPE.getValue(), this.type, true);
|
||||||
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.USAGE.getValue(), this.usage, true);
|
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.USAGE.getValue(), this.usage, true);
|
||||||
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.TAGID.getValue(), this.tagId==null?0L:this.tagId.getId());
|
handlePropertyUpdate(command, actualChanges, GLAccountJsonInputParams.TAGID.getValue(),
|
||||||
|
this.tagId == null ? 0L : this.tagId.getId());
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +208,7 @@ public class GLAccount extends AbstractPersistable<Long> {
|
|||||||
public Integer getType() {
|
public Integer getType() {
|
||||||
return this.type;
|
return this.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateHierarchy() {
|
public void generateHierarchy() {
|
||||||
|
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
@@ -216,21 +217,21 @@ public class GLAccount extends AbstractPersistable<Long> {
|
|||||||
this.hierarchy = ".";
|
this.hierarchy = ".";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String hierarchyOf(final Long id) {
|
private String hierarchyOf(final Long id) {
|
||||||
return this.hierarchy + id.toString() + ".";
|
return this.hierarchy + id.toString() + ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDetailAccount() {
|
public boolean isDetailAccount() {
|
||||||
return GLAccountUsage.DETAIL.getValue().equals(this.usage);
|
return GLAccountUsage.DETAIL.getValue().equals(this.usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateTagId(CodeValue tagID) {
|
public void updateTagId(CodeValue tagID) {
|
||||||
this.tagId = tagID;
|
this.tagId = tagID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateParentAccount(GLAccount parentAccount) {
|
public void updateParentAccount(GLAccount parentAccount) {
|
||||||
this.parent=parentAccount;
|
this.parent = parentAccount;
|
||||||
this.generateHierarchy();
|
this.generateHierarchy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+15
-15
@@ -66,24 +66,24 @@ public enum GLAccountType {
|
|||||||
return name().toString();
|
return name().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAssetType() {
|
public boolean isAssetType() {
|
||||||
return this.value.equals(GLAccountType.ASSET.getValue());
|
return this.value.equals(GLAccountType.ASSET.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLiabilityType() {
|
public boolean isLiabilityType() {
|
||||||
return this.value.equals(GLAccountType.LIABILITY.getValue());
|
return this.value.equals(GLAccountType.LIABILITY.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEquityType() {
|
public boolean isEquityType() {
|
||||||
return this.value.equals(GLAccountType.EQUITY.getValue());
|
return this.value.equals(GLAccountType.EQUITY.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isIncomeType() {
|
public boolean isIncomeType() {
|
||||||
return this.value.equals(GLAccountType.INCOME.getValue());
|
return this.value.equals(GLAccountType.INCOME.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isExpenseType() {
|
public boolean isExpenseType() {
|
||||||
return this.value.equals(GLAccountType.EXPENSE.getValue());
|
return this.value.equals(GLAccountType.EXPENSE.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Executable
+77
@@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.accounting.journalentry.data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SavingsDTO {
|
||||||
|
|
||||||
|
private Long savingsId;
|
||||||
|
private Long savingsProductId;
|
||||||
|
private Long officeId;
|
||||||
|
private boolean cashBasedAccountingEnabled;
|
||||||
|
private boolean accrualBasedAccountingEnabled;
|
||||||
|
private List<SavingsTransactionDTO> newSavingsTransactions;
|
||||||
|
|
||||||
|
public SavingsDTO(final Long savingsId, final Long savingsProductId, final Long officeId, final boolean cashBasedAccountingEnabled,
|
||||||
|
final boolean accrualBasedAccountingEnabled, final List<SavingsTransactionDTO> newSavingsTransactions) {
|
||||||
|
this.savingsId = savingsId;
|
||||||
|
this.savingsProductId = savingsProductId;
|
||||||
|
this.officeId = officeId;
|
||||||
|
this.cashBasedAccountingEnabled = cashBasedAccountingEnabled;
|
||||||
|
this.accrualBasedAccountingEnabled = accrualBasedAccountingEnabled;
|
||||||
|
this.newSavingsTransactions = newSavingsTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getSavingsId() {
|
||||||
|
return this.savingsId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSavingsId(Long savingsId) {
|
||||||
|
this.savingsId = savingsId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getSavingsProductId() {
|
||||||
|
return this.savingsProductId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSavingsProductId(Long savingsProductId) {
|
||||||
|
this.savingsProductId = savingsProductId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getOfficeId() {
|
||||||
|
return this.officeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOfficeId(Long officeId) {
|
||||||
|
this.officeId = officeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCashBasedAccountingEnabled() {
|
||||||
|
return this.cashBasedAccountingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCashBasedAccountingEnabled(boolean cashBasedAccountingEnabled) {
|
||||||
|
this.cashBasedAccountingEnabled = cashBasedAccountingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAccrualBasedAccountingEnabled() {
|
||||||
|
return this.accrualBasedAccountingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccrualBasedAccountingEnabled(boolean accrualBasedAccountingEnabled) {
|
||||||
|
this.accrualBasedAccountingEnabled = accrualBasedAccountingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SavingsTransactionDTO> getNewSavingsTransactions() {
|
||||||
|
return this.newSavingsTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewSavingsTransactions(List<SavingsTransactionDTO> newSavingsTransactions) {
|
||||||
|
this.newSavingsTransactions = newSavingsTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.accounting.journalentry.data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionEnumData;
|
||||||
|
|
||||||
|
public class SavingsTransactionDTO {
|
||||||
|
|
||||||
|
private final String transactionId;
|
||||||
|
private final Date transactionDate;
|
||||||
|
private final Long paymentTypeId;
|
||||||
|
private final SavingsAccountTransactionEnumData transactionType;
|
||||||
|
|
||||||
|
private final BigDecimal amount;
|
||||||
|
|
||||||
|
/*** Boolean values determines if the transaction is reversed ***/
|
||||||
|
private final boolean reversed;
|
||||||
|
|
||||||
|
public SavingsTransactionDTO(final Long paymentTypeId, final String transactionId, final Date transactionDate,
|
||||||
|
final SavingsAccountTransactionEnumData transactionType, final BigDecimal amount, final boolean reversed) {
|
||||||
|
this.paymentTypeId = paymentTypeId;
|
||||||
|
this.transactionId = transactionId;
|
||||||
|
this.transactionDate = transactionDate;
|
||||||
|
this.amount = amount;
|
||||||
|
this.reversed = reversed;
|
||||||
|
this.transactionType = transactionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTransactionId() {
|
||||||
|
return this.transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getTransactionDate() {
|
||||||
|
return this.transactionDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getPaymentTypeId() {
|
||||||
|
return this.paymentTypeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SavingsAccountTransactionEnumData getTransactionType() {
|
||||||
|
return this.transactionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getAmount() {
|
||||||
|
return this.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReversed() {
|
||||||
|
return this.reversed;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.accounting.journalentry.service;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.journalentry.data.SavingsDTO;
|
||||||
|
|
||||||
|
public interface AccountingProcessorForSavings {
|
||||||
|
|
||||||
|
void createJournalEntriesForSavings(SavingsDTO savingsDTO);
|
||||||
|
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.accounting.journalentry.service;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.journalentry.data.SavingsDTO;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class AccountingProcessorForSavingsFactory {
|
||||||
|
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AccountingProcessorForSavingsFactory(ApplicationContext applicationContext) {
|
||||||
|
this.applicationContext = applicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Looks like overkill for now, but wanted to keep the savings side of
|
||||||
|
* accounting identical to that of Loans (would we need an Accrual based
|
||||||
|
* accounting in the future?)
|
||||||
|
***/
|
||||||
|
public AccountingProcessorForSavings determineProcessor(final SavingsDTO savingsDTO) {
|
||||||
|
|
||||||
|
AccountingProcessorForSavings accountingProcessorForSavings = null;
|
||||||
|
|
||||||
|
if (savingsDTO.isCashBasedAccountingEnabled()) {
|
||||||
|
accountingProcessorForSavings = applicationContext.getBean("cashBasedAccountingProcessorForSavings",
|
||||||
|
AccountingProcessorForSavings.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
return accountingProcessorForSavings;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+113
@@ -16,9 +16,12 @@ import org.mifosplatform.accounting.closure.domain.GLClosure;
|
|||||||
import org.mifosplatform.accounting.closure.domain.GLClosureRepository;
|
import org.mifosplatform.accounting.closure.domain.GLClosureRepository;
|
||||||
import org.mifosplatform.accounting.common.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN;
|
import org.mifosplatform.accounting.common.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN;
|
||||||
import org.mifosplatform.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
|
import org.mifosplatform.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_SAVINGS;
|
||||||
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
|
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
|
||||||
import org.mifosplatform.accounting.journalentry.data.LoanDTO;
|
import org.mifosplatform.accounting.journalentry.data.LoanDTO;
|
||||||
import org.mifosplatform.accounting.journalentry.data.LoanTransactionDTO;
|
import org.mifosplatform.accounting.journalentry.data.LoanTransactionDTO;
|
||||||
|
import org.mifosplatform.accounting.journalentry.data.SavingsDTO;
|
||||||
|
import org.mifosplatform.accounting.journalentry.data.SavingsTransactionDTO;
|
||||||
import org.mifosplatform.accounting.journalentry.domain.JournalEntry;
|
import org.mifosplatform.accounting.journalentry.domain.JournalEntry;
|
||||||
import org.mifosplatform.accounting.journalentry.domain.JournalEntryRepository;
|
import org.mifosplatform.accounting.journalentry.domain.JournalEntryRepository;
|
||||||
import org.mifosplatform.accounting.journalentry.domain.JournalEntryType;
|
import org.mifosplatform.accounting.journalentry.domain.JournalEntryType;
|
||||||
@@ -30,6 +33,7 @@ import org.mifosplatform.accounting.producttoaccountmapping.domain.ProductToGLAc
|
|||||||
import org.mifosplatform.organisation.office.domain.Office;
|
import org.mifosplatform.organisation.office.domain.Office;
|
||||||
import org.mifosplatform.organisation.office.domain.OfficeRepository;
|
import org.mifosplatform.organisation.office.domain.OfficeRepository;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData;
|
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData;
|
||||||
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionEnumData;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -83,6 +87,35 @@ public class AccountingProcessorHelper {
|
|||||||
return new LoanDTO(loanId, loanProductId, officeId, cashBasedAccountingEnabled, accrualBasedAccountingEnabled, newLoanTransactions);
|
return new LoanDTO(loanId, loanProductId, officeId, cashBasedAccountingEnabled, accrualBasedAccountingEnabled, newLoanTransactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SavingsDTO populateSavingsDtoFromMap(final Map<String, Object> accountingBridgeData, final boolean cashBasedAccountingEnabled,
|
||||||
|
final boolean accrualBasedAccountingEnabled) {
|
||||||
|
final Long loanId = (Long) accountingBridgeData.get("savingsId");
|
||||||
|
final Long loanProductId = (Long) accountingBridgeData.get("savingsProductId");
|
||||||
|
final Long officeId = (Long) accountingBridgeData.get("officeId");
|
||||||
|
final List<SavingsTransactionDTO> newSavingsTransactions = new ArrayList<SavingsTransactionDTO>();
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final List<Map<String, Object>> newTransactionsMap = (List<Map<String, Object>>) accountingBridgeData.get("newSavingsTransactions");
|
||||||
|
|
||||||
|
for (final Map<String, Object> map : newTransactionsMap) {
|
||||||
|
final String transactionId = ((Long) map.get("id")).toString();
|
||||||
|
final Date transactionDate = ((LocalDate) map.get("date")).toDate();
|
||||||
|
final SavingsAccountTransactionEnumData transactionType = (SavingsAccountTransactionEnumData) map.get("type");
|
||||||
|
final BigDecimal amount = (BigDecimal) map.get("amount");
|
||||||
|
final boolean reversed = (Boolean) map.get("reversed");
|
||||||
|
final Long paymentTypeId = (Long) map.get("paymentTypeId");
|
||||||
|
|
||||||
|
final SavingsTransactionDTO transaction = new SavingsTransactionDTO(paymentTypeId, transactionId, transactionDate,
|
||||||
|
transactionType, amount, reversed);
|
||||||
|
|
||||||
|
newSavingsTransactions.add(transaction);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SavingsDTO(loanId, loanProductId, officeId, cashBasedAccountingEnabled, accrualBasedAccountingEnabled,
|
||||||
|
newSavingsTransactions);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method that creates a pair of related Debits and Credits for
|
* Convenience method that creates a pair of related Debits and Credits for
|
||||||
* Accrual Based accounting.
|
* Accrual Based accounting.
|
||||||
@@ -118,6 +151,41 @@ public class AccountingProcessorHelper {
|
|||||||
transactionId, transactionDate, amount);
|
transactionId, transactionDate, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method that creates a pair of related Debits and Credits for
|
||||||
|
* Cash Based accounting.
|
||||||
|
*
|
||||||
|
* The target accounts for debits and credits are switched in case of a
|
||||||
|
* reversal
|
||||||
|
*
|
||||||
|
* @param office
|
||||||
|
* @param accountTypeToBeDebited
|
||||||
|
* Enum of the placeholder GLAccount to be debited
|
||||||
|
* @param accountTypeToBeCredited
|
||||||
|
* Enum of the placeholder of the GLAccount to be credited
|
||||||
|
* @param savingsProductId
|
||||||
|
* @param paymentTypeId
|
||||||
|
* @param loanId
|
||||||
|
* @param transactionId
|
||||||
|
* @param transactionDate
|
||||||
|
* @param amount
|
||||||
|
* @param isReversal
|
||||||
|
*/
|
||||||
|
public void createCashBasedJournalEntriesAndReversalsForSavings(final Office office,
|
||||||
|
final CASH_ACCOUNTS_FOR_SAVINGS accountTypeToBeDebited, final CASH_ACCOUNTS_FOR_SAVINGS accountTypeToBeCredited,
|
||||||
|
final Long savingsProductId, final Long paymentTypeId, final Long loanId, final String transactionId,
|
||||||
|
final Date transactionDate, final BigDecimal amount, final Boolean isReversal) {
|
||||||
|
int accountTypeToDebitId = accountTypeToBeDebited.getValue();
|
||||||
|
int accountTypeToCreditId = accountTypeToBeCredited.getValue();
|
||||||
|
// reverse debits and credits for reversals
|
||||||
|
if (isReversal) {
|
||||||
|
accountTypeToDebitId = accountTypeToBeCredited.getValue();
|
||||||
|
accountTypeToCreditId = accountTypeToBeDebited.getValue();
|
||||||
|
}
|
||||||
|
createJournalEntriesForSavings(office, accountTypeToDebitId, accountTypeToCreditId, savingsProductId, paymentTypeId, loanId,
|
||||||
|
transactionId, transactionDate, amount);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method that creates a pair of related Debits and Credits for
|
* Convenience method that creates a pair of related Debits and Credits for
|
||||||
* Cash Based accounting.
|
* Cash Based accounting.
|
||||||
@@ -216,6 +284,15 @@ public class AccountingProcessorHelper {
|
|||||||
createCreditJournalEntryForLoan(office, creditAccount, loanId, transactionId, transactionDate, amount);
|
createCreditJournalEntryForLoan(office, creditAccount, loanId, transactionId, transactionDate, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createJournalEntriesForSavings(final Office office, final int accountTypeToDebitId, final int accountTypeToCreditId,
|
||||||
|
final Long savingsProductId, final Long paymentTypeId, final Long savingsId, final String transactionId,
|
||||||
|
final Date transactionDate, final BigDecimal amount) {
|
||||||
|
GLAccount debitAccount = getLinkedGLAccountForSavingsProduct(savingsProductId, accountTypeToDebitId, paymentTypeId);
|
||||||
|
GLAccount creditAccount = getLinkedGLAccountForSavingsProduct(savingsProductId, accountTypeToCreditId, paymentTypeId);
|
||||||
|
createDebitJournalEntryForSavings(office, debitAccount, savingsId, transactionId, transactionDate, amount);
|
||||||
|
createCreditJournalEntryForSavings(office, creditAccount, savingsId, transactionId, transactionDate, amount);
|
||||||
|
}
|
||||||
|
|
||||||
private void createDebitJournalEntryOrReversalForLoan(final Office office, final int accountMappingTypeId, final Long loanProductId,
|
private void createDebitJournalEntryOrReversalForLoan(final Office office, final int accountMappingTypeId, final Long loanProductId,
|
||||||
final Long paymentTypeId, final Long loanId, final String transactionId, final Date transactionDate, final BigDecimal amount,
|
final Long paymentTypeId, final Long loanId, final String transactionId, final Date transactionDate, final BigDecimal amount,
|
||||||
final Boolean isReversal) {
|
final Boolean isReversal) {
|
||||||
@@ -246,6 +323,14 @@ public class AccountingProcessorHelper {
|
|||||||
this.glJournalEntryRepository.saveAndFlush(journalEntry);
|
this.glJournalEntryRepository.saveAndFlush(journalEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createCreditJournalEntryForSavings(final Office office, final GLAccount account, final Long savingsId,
|
||||||
|
final String transactionId, final Date transactionDate, final BigDecimal amount) {
|
||||||
|
final boolean manualEntry = false;
|
||||||
|
final JournalEntry journalEntry = JournalEntry.createNew(office, account, transactionId, manualEntry, transactionDate,
|
||||||
|
JournalEntryType.CREDIT, amount, null, PortfolioProductType.SAVING.getValue(), savingsId, null);
|
||||||
|
this.glJournalEntryRepository.saveAndFlush(journalEntry);
|
||||||
|
}
|
||||||
|
|
||||||
private void createDebitJournalEntryForLoan(final Office office, final GLAccount account, final Long loanId,
|
private void createDebitJournalEntryForLoan(final Office office, final GLAccount account, final Long loanId,
|
||||||
final String transactionId, final Date transactionDate, final BigDecimal amount) {
|
final String transactionId, final Date transactionDate, final BigDecimal amount) {
|
||||||
final boolean manualEntry = false;
|
final boolean manualEntry = false;
|
||||||
@@ -254,6 +339,14 @@ public class AccountingProcessorHelper {
|
|||||||
this.glJournalEntryRepository.saveAndFlush(journalEntry);
|
this.glJournalEntryRepository.saveAndFlush(journalEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createDebitJournalEntryForSavings(final Office office, final GLAccount account, final Long savingsId,
|
||||||
|
final String transactionId, final Date transactionDate, final BigDecimal amount) {
|
||||||
|
final boolean manualEntry = false;
|
||||||
|
final JournalEntry journalEntry = JournalEntry.createNew(office, account, transactionId, manualEntry, transactionDate,
|
||||||
|
JournalEntryType.DEBIT, amount, null, PortfolioProductType.SAVING.getValue(), savingsId, null);
|
||||||
|
this.glJournalEntryRepository.saveAndFlush(journalEntry);
|
||||||
|
}
|
||||||
|
|
||||||
private GLAccount getLinkedGLAccountForLoanProduct(final Long loanProductId, final int accountMappingTypeId, final Long paymentTypeId) {
|
private GLAccount getLinkedGLAccountForLoanProduct(final Long loanProductId, final int accountMappingTypeId, final Long paymentTypeId) {
|
||||||
ProductToGLAccountMapping accountMapping = this.accountMappingRepository.findCoreProductToFinAccountMapping(loanProductId,
|
ProductToGLAccountMapping accountMapping = this.accountMappingRepository.findCoreProductToFinAccountMapping(loanProductId,
|
||||||
PortfolioProductType.LOAN.getValue(), accountMappingTypeId);
|
PortfolioProductType.LOAN.getValue(), accountMappingTypeId);
|
||||||
@@ -272,4 +365,24 @@ public class AccountingProcessorHelper {
|
|||||||
}
|
}
|
||||||
return accountMapping.getGlAccount();
|
return accountMapping.getGlAccount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private GLAccount getLinkedGLAccountForSavingsProduct(final Long savingsProductId, final int accountMappingTypeId,
|
||||||
|
final Long paymentTypeId) {
|
||||||
|
ProductToGLAccountMapping accountMapping = this.accountMappingRepository.findCoreProductToFinAccountMapping(savingsProductId,
|
||||||
|
PortfolioProductType.SAVING.getValue(), accountMappingTypeId);
|
||||||
|
/****
|
||||||
|
* Get more specific mapping for FUND source accounts (based on payment
|
||||||
|
* channels). Note that fund source placeholder ID would be same for
|
||||||
|
* both cash and accrual accounts
|
||||||
|
***/
|
||||||
|
if (accountMappingTypeId == CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue()) {
|
||||||
|
ProductToGLAccountMapping paymentChannelSpecificAccountMapping = this.accountMappingRepository
|
||||||
|
.findByProductIdAndProductTypeAndFinancialAccountTypeAndPaymentTypeId(savingsProductId,
|
||||||
|
PortfolioProductType.SAVING.getValue(), accountMappingTypeId, paymentTypeId);
|
||||||
|
if (paymentChannelSpecificAccountMapping != null) {
|
||||||
|
accountMapping = paymentChannelSpecificAccountMapping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return accountMapping.getGlAccount();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.accounting.journalentry.service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.closure.domain.GLClosure;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_SAVINGS;
|
||||||
|
import org.mifosplatform.accounting.journalentry.data.SavingsDTO;
|
||||||
|
import org.mifosplatform.accounting.journalentry.data.SavingsTransactionDTO;
|
||||||
|
import org.mifosplatform.organisation.office.domain.Office;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class CashBasedAccountingProcessorForSavings implements AccountingProcessorForSavings {
|
||||||
|
|
||||||
|
private final AccountingProcessorHelper helper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public CashBasedAccountingProcessorForSavings(final AccountingProcessorHelper accountingProcessorHelper) {
|
||||||
|
this.helper = accountingProcessorHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createJournalEntriesForSavings(SavingsDTO savingsDTO) {
|
||||||
|
final GLClosure latestGLClosure = this.helper.getLatestClosureByBranch(savingsDTO.getOfficeId());
|
||||||
|
final Office office = this.helper.getOfficeById(savingsDTO.getOfficeId());
|
||||||
|
final Long savingsProductId = savingsDTO.getSavingsProductId();
|
||||||
|
final Long savingsId = savingsDTO.getSavingsId();
|
||||||
|
for (final SavingsTransactionDTO savingsTransactionDTO : savingsDTO.getNewSavingsTransactions()) {
|
||||||
|
final Date transactionDate = savingsTransactionDTO.getTransactionDate();
|
||||||
|
final String transactionId = savingsTransactionDTO.getTransactionId();
|
||||||
|
final Long paymentTypeId = savingsTransactionDTO.getPaymentTypeId();
|
||||||
|
final boolean isReversal = savingsTransactionDTO.isReversed();
|
||||||
|
final BigDecimal amount = savingsTransactionDTO.getAmount();
|
||||||
|
|
||||||
|
helper.checkForBranchClosures(latestGLClosure, transactionDate);
|
||||||
|
|
||||||
|
/** Handle Deposits and reversals of deposits **/
|
||||||
|
if (savingsTransactionDTO.getTransactionType().isDeposit()) {
|
||||||
|
helper.createCashBasedJournalEntriesAndReversalsForSavings(office, CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_REFERENCE,
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL, savingsProductId, paymentTypeId, savingsId, transactionId,
|
||||||
|
transactionDate, amount, isReversal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handle withdrawals and reversals of withdrawals **/
|
||||||
|
else if (savingsTransactionDTO.getTransactionType().isWithdrawal()) {
|
||||||
|
helper.createCashBasedJournalEntriesAndReversalsForSavings(office, CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL,
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_REFERENCE, savingsProductId, paymentTypeId, savingsId, transactionId,
|
||||||
|
transactionDate, amount, isReversal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Interest Applications and reversals of Interest
|
||||||
|
* Applications
|
||||||
|
**/
|
||||||
|
else if (savingsTransactionDTO.getTransactionType().isInterestPosting()) {
|
||||||
|
helper.createCashBasedJournalEntriesAndReversalsForSavings(office, CASH_ACCOUNTS_FOR_SAVINGS.INTEREST_ON_SAVINGS,
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL, savingsProductId, paymentTypeId, savingsId, transactionId,
|
||||||
|
transactionDate, amount, isReversal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handle Fees Deductions and reversals of Fees Deductions **/
|
||||||
|
else if (savingsTransactionDTO.getTransactionType().isFeeDeduction()) {
|
||||||
|
helper.createCashBasedJournalEntriesAndReversalsForSavings(office, CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL,
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_FEES, savingsProductId, paymentTypeId, savingsId, transactionId,
|
||||||
|
transactionDate, amount, isReversal);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -17,4 +17,6 @@ public interface JournalEntryWritePlatformService {
|
|||||||
CommandProcessingResult revertJournalEntry(JsonCommand command);
|
CommandProcessingResult revertJournalEntry(JsonCommand command);
|
||||||
|
|
||||||
void createJournalEntriesForLoan(Map<String, Object> accountingBridgeData);
|
void createJournalEntriesForLoan(Map<String, Object> accountingBridgeData);
|
||||||
|
|
||||||
|
void createJournalEntriesForSavings(Map<String, Object> accountingBridgeData);
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-18
@@ -22,6 +22,7 @@ import org.mifosplatform.accounting.journalentry.api.JournalEntryJsonInputParams
|
|||||||
import org.mifosplatform.accounting.journalentry.command.JournalEntryCommand;
|
import org.mifosplatform.accounting.journalentry.command.JournalEntryCommand;
|
||||||
import org.mifosplatform.accounting.journalentry.command.SingleDebitOrCreditEntryCommand;
|
import org.mifosplatform.accounting.journalentry.command.SingleDebitOrCreditEntryCommand;
|
||||||
import org.mifosplatform.accounting.journalentry.data.LoanDTO;
|
import org.mifosplatform.accounting.journalentry.data.LoanDTO;
|
||||||
|
import org.mifosplatform.accounting.journalentry.data.SavingsDTO;
|
||||||
import org.mifosplatform.accounting.journalentry.domain.JournalEntry;
|
import org.mifosplatform.accounting.journalentry.domain.JournalEntry;
|
||||||
import org.mifosplatform.accounting.journalentry.domain.JournalEntryRepository;
|
import org.mifosplatform.accounting.journalentry.domain.JournalEntryRepository;
|
||||||
import org.mifosplatform.accounting.journalentry.domain.JournalEntryType;
|
import org.mifosplatform.accounting.journalentry.domain.JournalEntryType;
|
||||||
@@ -56,6 +57,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
|
|||||||
private final JournalEntryRepository glJournalEntryRepository;
|
private final JournalEntryRepository glJournalEntryRepository;
|
||||||
private final OfficeRepository officeRepository;
|
private final OfficeRepository officeRepository;
|
||||||
private final AccountingProcessorForLoanFactory accountingProcessorForLoanFactory;
|
private final AccountingProcessorForLoanFactory accountingProcessorForLoanFactory;
|
||||||
|
private final AccountingProcessorForSavingsFactory accountingProcessorForSavingsFactory;
|
||||||
private final AccountingProcessorHelper helper;
|
private final AccountingProcessorHelper helper;
|
||||||
private final JournalEntryCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
private final JournalEntryCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||||
private final AccountingRuleRepository accountingRuleRepository;
|
private final AccountingRuleRepository accountingRuleRepository;
|
||||||
@@ -65,13 +67,15 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
|
|||||||
final JournalEntryRepository glJournalEntryRepository, final OfficeRepository officeRepository,
|
final JournalEntryRepository glJournalEntryRepository, final OfficeRepository officeRepository,
|
||||||
final GLAccountRepository glAccountRepository, final JournalEntryCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
final GLAccountRepository glAccountRepository, final JournalEntryCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
||||||
final AccountingProcessorHelper accountingProcessorHelper, final AccountingRuleRepository accountingRuleRepository,
|
final AccountingProcessorHelper accountingProcessorHelper, final AccountingRuleRepository accountingRuleRepository,
|
||||||
final AccountingProcessorForLoanFactory accountingProcessorForLoanFactory) {
|
final AccountingProcessorForLoanFactory accountingProcessorForLoanFactory,
|
||||||
|
final AccountingProcessorForSavingsFactory accountingProcessorForSavingsFactory) {
|
||||||
this.glClosureRepository = glClosureRepository;
|
this.glClosureRepository = glClosureRepository;
|
||||||
this.officeRepository = officeRepository;
|
this.officeRepository = officeRepository;
|
||||||
this.glJournalEntryRepository = glJournalEntryRepository;
|
this.glJournalEntryRepository = glJournalEntryRepository;
|
||||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||||
this.glAccountRepository = glAccountRepository;
|
this.glAccountRepository = glAccountRepository;
|
||||||
this.accountingProcessorForLoanFactory = accountingProcessorForLoanFactory;
|
this.accountingProcessorForLoanFactory = accountingProcessorForLoanFactory;
|
||||||
|
this.accountingProcessorForSavingsFactory = accountingProcessorForSavingsFactory;
|
||||||
this.helper = accountingProcessorHelper;
|
this.helper = accountingProcessorHelper;
|
||||||
this.accountingRuleRepository = accountingRuleRepository;
|
this.accountingRuleRepository = accountingRuleRepository;
|
||||||
}
|
}
|
||||||
@@ -87,9 +91,9 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
|
|||||||
final Long officeId = command.longValueOfParameterNamed(JournalEntryJsonInputParams.OFFICE_ID.getValue());
|
final Long officeId = command.longValueOfParameterNamed(JournalEntryJsonInputParams.OFFICE_ID.getValue());
|
||||||
final Office office = this.officeRepository.findOne(officeId);
|
final Office office = this.officeRepository.findOne(officeId);
|
||||||
if (office == null) { throw new OfficeNotFoundException(officeId); }
|
if (office == null) { throw new OfficeNotFoundException(officeId); }
|
||||||
|
|
||||||
final Long accountRuleId = command.longValueOfParameterNamed(JournalEntryJsonInputParams.ACCOUNTING_RULE.getValue());
|
final Long accountRuleId = command.longValueOfParameterNamed(JournalEntryJsonInputParams.ACCOUNTING_RULE.getValue());
|
||||||
|
|
||||||
validateBusinessRulesForJournalEntries(journalEntryCommand);
|
validateBusinessRulesForJournalEntries(journalEntryCommand);
|
||||||
|
|
||||||
/** Set a transaction Id and save these Journal entries **/
|
/** Set a transaction Id and save these Journal entries **/
|
||||||
@@ -99,7 +103,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
|
|||||||
final boolean manualEntry = true;
|
final boolean manualEntry = true;
|
||||||
|
|
||||||
if (accountRuleId != null) {
|
if (accountRuleId != null) {
|
||||||
|
|
||||||
final Long accountingRuleId = command.longValueOfParameterNamed(JournalEntryJsonInputParams.ACCOUNTING_RULE.getValue());
|
final Long accountingRuleId = command.longValueOfParameterNamed(JournalEntryJsonInputParams.ACCOUNTING_RULE.getValue());
|
||||||
final BigDecimal amount = command.bigDecimalValueOfParameterNamed(JournalEntryJsonInputParams.AMOUNT.getValue());
|
final BigDecimal amount = command.bigDecimalValueOfParameterNamed(JournalEntryJsonInputParams.AMOUNT.getValue());
|
||||||
final AccountingRule accountingRule = this.accountingRuleRepository.findOne(accountingRuleId);
|
final AccountingRule accountingRule = this.accountingRuleRepository.findOne(accountingRuleId);
|
||||||
@@ -112,24 +116,23 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
|
|||||||
if (StringUtils.isNotBlank(journalEntryCommand.getComments())) {
|
if (StringUtils.isNotBlank(journalEntryCommand.getComments())) {
|
||||||
description = journalEntryCommand.getComments();
|
description = journalEntryCommand.getComments();
|
||||||
}
|
}
|
||||||
|
|
||||||
JournalEntry creditEntry = JournalEntry.createNew(office, creditAccountHead, transactionId, manualEntry, transactionDate,
|
JournalEntry creditEntry = JournalEntry.createNew(office, creditAccountHead, transactionId, manualEntry, transactionDate,
|
||||||
JournalEntryType.CREDIT, amount, description, null, null, referenceNumber);
|
JournalEntryType.CREDIT, amount, description, null, null, referenceNumber);
|
||||||
this.glJournalEntryRepository.saveAndFlush(creditEntry);
|
this.glJournalEntryRepository.saveAndFlush(creditEntry);
|
||||||
|
|
||||||
JournalEntry debitEntry = JournalEntry.createNew(office, debitAccountHead, transactionId, manualEntry, transactionDate,
|
JournalEntry debitEntry = JournalEntry.createNew(office, debitAccountHead, transactionId, manualEntry, transactionDate,
|
||||||
JournalEntryType.DEBIT, amount, description, null, null, referenceNumber);
|
JournalEntryType.DEBIT, amount, description, null, null, referenceNumber);
|
||||||
this.glJournalEntryRepository.saveAndFlush(debitEntry);
|
this.glJournalEntryRepository.saveAndFlush(debitEntry);
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
saveAllDebitOrCreditEntries(journalEntryCommand, office, transactionDate, journalEntryCommand.getDebits(), transactionId,
|
saveAllDebitOrCreditEntries(journalEntryCommand, office, transactionDate, journalEntryCommand.getDebits(), transactionId,
|
||||||
JournalEntryType.DEBIT, referenceNumber);
|
JournalEntryType.DEBIT, referenceNumber);
|
||||||
|
|
||||||
saveAllDebitOrCreditEntries(journalEntryCommand, office, transactionDate, journalEntryCommand.getCredits(), transactionId,
|
saveAllDebitOrCreditEntries(journalEntryCommand, office, transactionDate, journalEntryCommand.getCredits(), transactionId,
|
||||||
JournalEntryType.CREDIT, referenceNumber);
|
JournalEntryType.CREDIT, referenceNumber);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(officeId)
|
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(officeId)
|
||||||
@@ -146,8 +149,8 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
|
|||||||
* disabled
|
* disabled
|
||||||
**/
|
**/
|
||||||
if (creditOrDebitAccountHead.isDisabled()) {
|
if (creditOrDebitAccountHead.isDisabled()) {
|
||||||
throw new JournalEntryInvalidException(GL_JOURNAL_ENTRY_INVALID_REASON.GL_ACCOUNT_DISABLED, null, creditOrDebitAccountHead.getName(),
|
throw new JournalEntryInvalidException(GL_JOURNAL_ENTRY_INVALID_REASON.GL_ACCOUNT_DISABLED, null,
|
||||||
creditOrDebitAccountHead.getGlCode());
|
creditOrDebitAccountHead.getName(), creditOrDebitAccountHead.getGlCode());
|
||||||
} else if (!creditOrDebitAccountHead.isManualEntriesAllowed()) { throw new JournalEntryInvalidException(
|
} else if (!creditOrDebitAccountHead.isManualEntriesAllowed()) { throw new JournalEntryInvalidException(
|
||||||
GL_JOURNAL_ENTRY_INVALID_REASON.GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED, null, creditOrDebitAccountHead.getName(),
|
GL_JOURNAL_ENTRY_INVALID_REASON.GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED, null, creditOrDebitAccountHead.getName(),
|
||||||
creditOrDebitAccountHead.getGlCode()); }
|
creditOrDebitAccountHead.getGlCode()); }
|
||||||
@@ -204,6 +207,23 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public void createJournalEntriesForSavings(Map<String, Object> accountingBridgeData) {
|
||||||
|
|
||||||
|
final boolean cashBasedAccountingEnabled = (Boolean) accountingBridgeData.get("cashBasedAccountingEnabled");
|
||||||
|
final boolean accrualBasedAccountingEnabled = (Boolean) accountingBridgeData.get("accrualBasedAccountingEnabled");
|
||||||
|
|
||||||
|
if (cashBasedAccountingEnabled || accrualBasedAccountingEnabled) {
|
||||||
|
final SavingsDTO savingsDTO = helper.populateSavingsDtoFromMap(accountingBridgeData, cashBasedAccountingEnabled,
|
||||||
|
accrualBasedAccountingEnabled);
|
||||||
|
final AccountingProcessorForSavings accountingProcessorForSavings = this.accountingProcessorForSavingsFactory
|
||||||
|
.determineProcessor(savingsDTO);
|
||||||
|
accountingProcessorForSavings.createJournalEntriesForSavings(savingsDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void validateBusinessRulesForJournalEntries(final JournalEntryCommand command) {
|
private void validateBusinessRulesForJournalEntries(final JournalEntryCommand command) {
|
||||||
/** check if date of Journal entry is valid ***/
|
/** check if date of Journal entry is valid ***/
|
||||||
final LocalDate entryLocalDate = command.getTransactionDate();
|
final LocalDate entryLocalDate = command.getTransactionDate();
|
||||||
@@ -218,15 +238,15 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
|
|||||||
if (latestGLClosure.getClosingDate().after(transactionDate) || latestGLClosure.getClosingDate().equals(transactionDate)) { throw new JournalEntryInvalidException(
|
if (latestGLClosure.getClosingDate().after(transactionDate) || latestGLClosure.getClosingDate().equals(transactionDate)) { throw new JournalEntryInvalidException(
|
||||||
GL_JOURNAL_ENTRY_INVALID_REASON.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate(), null, null); }
|
GL_JOURNAL_ENTRY_INVALID_REASON.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate(), null, null); }
|
||||||
}
|
}
|
||||||
if(command.getAccountingRuleId() == null) {
|
if (command.getAccountingRuleId() == null) {
|
||||||
/*** check if credits and debits are valid **/
|
/*** check if credits and debits are valid **/
|
||||||
final SingleDebitOrCreditEntryCommand[] credits = command.getCredits();
|
final SingleDebitOrCreditEntryCommand[] credits = command.getCredits();
|
||||||
final SingleDebitOrCreditEntryCommand[] debits = command.getDebits();
|
final SingleDebitOrCreditEntryCommand[] debits = command.getDebits();
|
||||||
|
|
||||||
// atleast one debit or credit must be present
|
// atleast one debit or credit must be present
|
||||||
if ((credits == null || credits.length <= 0) || (debits == null || debits.length <= 0)) { throw new JournalEntryInvalidException(
|
if ((credits == null || credits.length <= 0) || (debits == null || debits.length <= 0)) { throw new JournalEntryInvalidException(
|
||||||
GL_JOURNAL_ENTRY_INVALID_REASON.NO_DEBITS_OR_CREDITS, null, null, null); }
|
GL_JOURNAL_ENTRY_INVALID_REASON.NO_DEBITS_OR_CREDITS, null, null, null); }
|
||||||
|
|
||||||
// sum of all debits must be = sum of all credits
|
// sum of all debits must be = sum of all credits
|
||||||
BigDecimal creditsSum = BigDecimal.ZERO;
|
BigDecimal creditsSum = BigDecimal.ZERO;
|
||||||
BigDecimal debitsSum = BigDecimal.ZERO;
|
BigDecimal debitsSum = BigDecimal.ZERO;
|
||||||
@@ -259,7 +279,6 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
|
|||||||
if (!StringUtils.isBlank(singleDebitOrCreditEntryCommand.getComments())) {
|
if (!StringUtils.isBlank(singleDebitOrCreditEntryCommand.getComments())) {
|
||||||
comments = singleDebitOrCreditEntryCommand.getComments();
|
comments = singleDebitOrCreditEntryCommand.getComments();
|
||||||
}
|
}
|
||||||
|
|
||||||
final JournalEntry glJournalEntry = JournalEntry.createNew(office, glAccount, transactionId, manualEntry, transactionDate,
|
final JournalEntry glJournalEntry = JournalEntry.createNew(office, glAccount, transactionId, manualEntry, transactionDate,
|
||||||
type, singleDebitOrCreditEntryCommand.getAmount(), comments, null, null, referenceNumber);
|
type, singleDebitOrCreditEntryCommand.getAmount(), comments, null, null, referenceNumber);
|
||||||
this.glJournalEntryRepository.saveAndFlush(glJournalEntry);
|
this.glJournalEntryRepository.saveAndFlush(glJournalEntry);
|
||||||
|
|||||||
+48
-5
@@ -10,7 +10,9 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingRuleType;
|
||||||
import org.mifosplatform.accounting.common.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
|
import org.mifosplatform.accounting.common.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.SAVINGS_PRODUCT_ACCOUNTING_PARAMS;
|
||||||
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
|
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
|
||||||
import org.mifosplatform.accounting.producttoaccountmapping.service.ProductToGLAccountMappingWritePlatformService;
|
import org.mifosplatform.accounting.producttoaccountmapping.service.ProductToGLAccountMappingWritePlatformService;
|
||||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||||
@@ -18,10 +20,10 @@ import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
|||||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.AccountingRuleType;
|
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.*;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
|
|
||||||
@@ -41,9 +43,9 @@ import com.google.gson.JsonElement;
|
|||||||
* till we have access to the domain object it would not be possible to detect
|
* till we have access to the domain object it would not be possible to detect
|
||||||
* if an accounting rule has actually been changed
|
* if an accounting rule has actually been changed
|
||||||
*
|
*
|
||||||
* Hence, method {@link #validateForCreate(String)} from this class is called
|
* Hence, method {@link #validateForLoanProductCreate(String)} from this class
|
||||||
* separately for validation only if an accounting rule change is detected by
|
* is called separately for validation only if an accounting rule change is
|
||||||
* {@link ProductToGLAccountMappingWritePlatformService}
|
* detected by {@link ProductToGLAccountMappingWritePlatformService}
|
||||||
*
|
*
|
||||||
* Also, the class is probably named wrong (*FromApiJsonDeserializer) should
|
* Also, the class is probably named wrong (*FromApiJsonDeserializer) should
|
||||||
* probably be named as (*Validator) instead
|
* probably be named as (*Validator) instead
|
||||||
@@ -59,7 +61,7 @@ public final class ProductToGLAccountMappingFromApiJsonDeserializer {
|
|||||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validateForCreate(final String json) {
|
public void validateForLoanProductCreate(final String json) {
|
||||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||||
|
|
||||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
@@ -126,6 +128,47 @@ public final class ProductToGLAccountMappingFromApiJsonDeserializer {
|
|||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void validateForSavingsProductCreate(final String json) {
|
||||||
|
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||||
|
|
||||||
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||||
|
.resource(SAVINGS_PRODUCT_RESOURCE_NAME);
|
||||||
|
|
||||||
|
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||||
|
|
||||||
|
// accounting related data validation
|
||||||
|
final Integer accountingRuleType = this.fromApiJsonHelper
|
||||||
|
.extractIntegerNamed(accountingRuleParamName, element, Locale.getDefault());
|
||||||
|
baseDataValidator.reset().parameter(accountingRuleParamName).value(accountingRuleType).notNull().inMinMaxRange(1, 3);
|
||||||
|
|
||||||
|
if (isCashBasedAccounting(accountingRuleType)) {
|
||||||
|
|
||||||
|
final Long savingsControlAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue())
|
||||||
|
.value(savingsControlAccountId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long savingsReferenceAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(), element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue())
|
||||||
|
.value(savingsReferenceAccountId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long interestOnSavingsAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue())
|
||||||
|
.value(interestOnSavingsAccountId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long incomeFromFeeId = fromApiJsonHelper.extractLongNamed(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
|
||||||
|
element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue()).value(incomeFromFeeId)
|
||||||
|
.notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isCashBasedAccounting(final Integer accountingRuleType) {
|
private boolean isCashBasedAccounting(final Integer accountingRuleType) {
|
||||||
return AccountingRuleType.CASH_BASED.getValue().equals(accountingRuleType);
|
return AccountingRuleType.CASH_BASED.getValue().equals(accountingRuleType);
|
||||||
}
|
}
|
||||||
|
|||||||
+203
@@ -0,0 +1,203 @@
|
|||||||
|
package org.mifosplatform.accounting.producttoaccountmapping.service;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.common.AccountingRuleType;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
|
||||||
|
import org.mifosplatform.accounting.glaccount.domain.GLAccountRepository;
|
||||||
|
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||||
|
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappingHelper {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public LoanProductToGLAccountMappingHelper(GLAccountRepository glAccountRepository,
|
||||||
|
ProductToGLAccountMappingRepository glAccountMappingRepository, FromJsonHelper fromApiJsonHelper,
|
||||||
|
CodeValueRepositoryWrapper codeValueRepositoryWrapper) {
|
||||||
|
super(glAccountRepository, glAccountMappingRepository, fromApiJsonHelper, codeValueRepositoryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Set of abstractions for saving Loan Products to GL Account Mappings ***/
|
||||||
|
|
||||||
|
public void saveLoanToAssetAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int placeHolderTypeId) {
|
||||||
|
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.ASSET, PortfolioProductType.LOAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveLoanToIncomeAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int placeHolderTypeId) {
|
||||||
|
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.INCOME, PortfolioProductType.LOAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveLoanToExpenseAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int placeHolderTypeId) {
|
||||||
|
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.EXPENSE, PortfolioProductType.LOAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Set of abstractions for merging Savings Products to GL Account Mappings ***/
|
||||||
|
public void mergeLoanToAssetAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||||
|
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.ASSET,
|
||||||
|
PortfolioProductType.LOAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mergeLoanToIncomeAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||||
|
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.INCOME,
|
||||||
|
PortfolioProductType.LOAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mergeLoanToExpenseAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||||
|
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.EXPENSE,
|
||||||
|
PortfolioProductType.LOAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Abstractions for payments channel related to loan products ***/
|
||||||
|
|
||||||
|
public void savePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||||
|
Map<String, Object> changes) {
|
||||||
|
savePaymentChannelToFundSourceMappings(command, element, productId, changes, PortfolioProductType.LOAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||||
|
Map<String, Object> changes) {
|
||||||
|
updatePaymentChannelToFundSourceMappings(command, element, productId, changes, PortfolioProductType.LOAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> populateChangesForNewLoanProductToGLAccountMappingCreation(final JsonElement element,
|
||||||
|
final AccountingRuleType accountingRuleType) {
|
||||||
|
final Map<String, Object> changes = new HashMap<String, Object>();
|
||||||
|
|
||||||
|
final Long fundAccountId = this.fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), element);
|
||||||
|
final Long loanPortfolioAccountId = this.fromApiJsonHelper.extractLongNamed(
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), element);
|
||||||
|
final Long incomeFromInterestId = this.fromApiJsonHelper.extractLongNamed(
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), element);
|
||||||
|
final Long incomeFromFeeId = this.fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
|
||||||
|
element);
|
||||||
|
final Long incomeFromPenaltyId = this.fromApiJsonHelper.extractLongNamed(
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), element);
|
||||||
|
final Long writeOffAccountId = this.fromApiJsonHelper.extractLongNamed(
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), element);
|
||||||
|
|
||||||
|
final Long receivableInterestAccountId = this.fromApiJsonHelper.extractLongNamed(
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(), element);
|
||||||
|
final Long receivableFeeAccountId = this.fromApiJsonHelper.extractLongNamed(
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), element);
|
||||||
|
final Long receivablePenaltyAccountId = this.fromApiJsonHelper.extractLongNamed(
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(), element);
|
||||||
|
|
||||||
|
switch (accountingRuleType) {
|
||||||
|
case NONE:
|
||||||
|
break;
|
||||||
|
case CASH_BASED:
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), fundAccountId);
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), loanPortfolioAccountId);
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), incomeFromInterestId);
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), incomeFromFeeId);
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), incomeFromPenaltyId);
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), writeOffAccountId);
|
||||||
|
break;
|
||||||
|
case ACCRUAL_BASED:
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), fundAccountId);
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), loanPortfolioAccountId);
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), incomeFromInterestId);
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), incomeFromFeeId);
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), incomeFromPenaltyId);
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), writeOffAccountId);
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(), receivableInterestAccountId);
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), receivableFeeAccountId);
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(), receivablePenaltyAccountId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Examines and updates each account mapping for given loan product with
|
||||||
|
* changes passed in from the Json element
|
||||||
|
*
|
||||||
|
* @param loanProductId
|
||||||
|
* @param changes
|
||||||
|
* @param element
|
||||||
|
* @param accountingRuleType
|
||||||
|
*/
|
||||||
|
public void handleChangesToLoanProductToGLAccountMappings(final Long loanProductId, final Map<String, Object> changes,
|
||||||
|
final JsonElement element, final AccountingRuleType accountingRuleType) {
|
||||||
|
switch (accountingRuleType) {
|
||||||
|
case NONE:
|
||||||
|
break;
|
||||||
|
case CASH_BASED:
|
||||||
|
// asset
|
||||||
|
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), loanProductId,
|
||||||
|
CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue(), CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.toString(), changes);
|
||||||
|
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), loanProductId,
|
||||||
|
CASH_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.getValue(), CASH_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.toString(), changes);
|
||||||
|
|
||||||
|
// income
|
||||||
|
mergeLoanToIncomeAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), loanProductId,
|
||||||
|
CASH_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.getValue(), CASH_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.toString(), changes);
|
||||||
|
mergeLoanToIncomeAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), loanProductId,
|
||||||
|
CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue(), CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.toString(), changes);
|
||||||
|
mergeLoanToIncomeAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(),
|
||||||
|
loanProductId, CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue(),
|
||||||
|
CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.toString(), changes);
|
||||||
|
|
||||||
|
// expenses
|
||||||
|
mergeLoanToExpenseAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(),
|
||||||
|
loanProductId, CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue(),
|
||||||
|
CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.toString(), changes);
|
||||||
|
break;
|
||||||
|
case ACCRUAL_BASED:
|
||||||
|
// assets (including receivables)
|
||||||
|
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), loanProductId,
|
||||||
|
ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE.toString(), changes);
|
||||||
|
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), loanProductId,
|
||||||
|
ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.toString(), changes);
|
||||||
|
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(),
|
||||||
|
loanProductId, ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE.getValue(),
|
||||||
|
ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE.toString(), changes);
|
||||||
|
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), loanProductId,
|
||||||
|
ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE.toString(), changes);
|
||||||
|
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(),
|
||||||
|
loanProductId, ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE.getValue(),
|
||||||
|
ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE.toString(), changes);
|
||||||
|
|
||||||
|
// income
|
||||||
|
mergeLoanToIncomeAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), loanProductId,
|
||||||
|
ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.toString(),
|
||||||
|
changes);
|
||||||
|
mergeLoanToIncomeAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), loanProductId,
|
||||||
|
ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.toString(),
|
||||||
|
changes);
|
||||||
|
mergeLoanToIncomeAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(),
|
||||||
|
loanProductId, ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue(),
|
||||||
|
ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.toString(), changes);
|
||||||
|
|
||||||
|
// expenses
|
||||||
|
mergeLoanToExpenseAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(),
|
||||||
|
loanProductId, ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue(),
|
||||||
|
ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.toString(), changes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteLoanProductToGLAccountMapping(final Long loanProductId) {
|
||||||
|
deleteProductToGLAccountMapping(loanProductId, PortfolioProductType.LOAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+229
@@ -0,0 +1,229 @@
|
|||||||
|
package org.mifosplatform.accounting.producttoaccountmapping.service;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
|
||||||
|
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
|
||||||
|
import org.mifosplatform.accounting.glaccount.domain.GLAccountRepository;
|
||||||
|
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||||
|
import org.mifosplatform.accounting.glaccount.exception.GLAccountNotFoundException;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.domain.ProductToGLAccountMapping;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingInvalidException;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingNotFoundException;
|
||||||
|
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
|
||||||
|
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||||
|
import org.mifosplatform.portfolio.paymentdetail.PaymentDetailConstants;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ProductToGLAccountMappingHelper {
|
||||||
|
|
||||||
|
protected final GLAccountRepository accountRepository;
|
||||||
|
protected final ProductToGLAccountMappingRepository accountMappingRepository;
|
||||||
|
protected final FromJsonHelper fromApiJsonHelper;
|
||||||
|
private final CodeValueRepositoryWrapper codeValueRepositoryWrapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ProductToGLAccountMappingHelper(final GLAccountRepository glAccountRepository,
|
||||||
|
final ProductToGLAccountMappingRepository glAccountMappingRepository, final FromJsonHelper fromApiJsonHelper,
|
||||||
|
final CodeValueRepositoryWrapper codeValueRepositoryWrapper) {
|
||||||
|
this.accountRepository = glAccountRepository;
|
||||||
|
this.accountMappingRepository = glAccountMappingRepository;
|
||||||
|
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
|
this.codeValueRepositoryWrapper = codeValueRepositoryWrapper;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveProductToAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int placeHolderTypeId, final GLAccountType expectedAccountType, final PortfolioProductType portfolioProductType) {
|
||||||
|
final Long accountId = this.fromApiJsonHelper.extractLongNamed(paramName, element);
|
||||||
|
final GLAccount glAccount = getAccountByIdAndType(paramName, expectedAccountType, accountId);
|
||||||
|
|
||||||
|
final ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping(glAccount, productId,
|
||||||
|
portfolioProductType.getValue(), placeHolderTypeId);
|
||||||
|
this.accountMappingRepository.save(accountMapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mergeProductToAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes,
|
||||||
|
final GLAccountType expectedAccountType, final PortfolioProductType portfolioProductType) {
|
||||||
|
final Long accountId = this.fromApiJsonHelper.extractLongNamed(paramName, element);
|
||||||
|
|
||||||
|
// get the existing product
|
||||||
|
if (accountId != null) {
|
||||||
|
final ProductToGLAccountMapping accountMapping = this.accountMappingRepository.findCoreProductToFinAccountMapping(productId,
|
||||||
|
portfolioProductType.getValue(), accountTypeId);
|
||||||
|
if (accountMapping == null) { throw new ProductToGLAccountMappingNotFoundException(portfolioProductType, productId,
|
||||||
|
accountTypeName); }
|
||||||
|
if (accountMapping.getGlAccount().getId() != accountId) {
|
||||||
|
final GLAccount glAccount = getAccountByIdAndType(paramName, expectedAccountType, accountId);
|
||||||
|
changes.put(paramName, accountId);
|
||||||
|
accountMapping.setGlAccount(glAccount);
|
||||||
|
this.accountMappingRepository.save(accountMapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the payment type to Fund source mappings for a particular
|
||||||
|
* product/product type (also populates the changes array if passed in)
|
||||||
|
*
|
||||||
|
* @param command
|
||||||
|
* @param element
|
||||||
|
* @param productId
|
||||||
|
* @param changes
|
||||||
|
*/
|
||||||
|
public void savePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||||
|
Map<String, Object> changes, final PortfolioProductType portfolioProductType) {
|
||||||
|
JsonArray paymentChannelMappingArray = fromApiJsonHelper.extractJsonArrayNamed(
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element);
|
||||||
|
if (paymentChannelMappingArray != null) {
|
||||||
|
if (changes != null) {
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
|
||||||
|
command.jsonFragment(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue()));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < paymentChannelMappingArray.size(); i++) {
|
||||||
|
final JsonObject jsonObject = paymentChannelMappingArray.get(i).getAsJsonObject();
|
||||||
|
final Long paymentTypeId = jsonObject.get(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_TYPE.getValue()).getAsLong();
|
||||||
|
final Long paymentSpecificFundAccountId = jsonObject.get(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue()).getAsLong();
|
||||||
|
savePaymentChannelToFundSourceMapping(productId, paymentTypeId, paymentSpecificFundAccountId, portfolioProductType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param command
|
||||||
|
* @param element
|
||||||
|
* @param productId
|
||||||
|
* @param changes
|
||||||
|
*/
|
||||||
|
public void updatePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||||
|
Map<String, Object> changes, final PortfolioProductType portfolioProductType) {
|
||||||
|
// find all existing payment Channel to Fund source Mappings
|
||||||
|
List<ProductToGLAccountMapping> existingPaymentChannelToFundSourceMappings = accountMappingRepository
|
||||||
|
.findAllPaymentTypeToFundSourceMappings(productId, portfolioProductType.getValue());
|
||||||
|
JsonArray paymentChannelMappingArray = fromApiJsonHelper.extractJsonArrayNamed(
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element);
|
||||||
|
/**
|
||||||
|
* Variable stores a map representation of Payment channels (key) and
|
||||||
|
* their fund sources (value) extracted from the passed in Jsoncommand
|
||||||
|
**/
|
||||||
|
Map<Long, Long> inputPaymentChannelFundSourceMap = new HashMap<Long, Long>();
|
||||||
|
/***
|
||||||
|
* Variable stores all payment types which have already been mapped to
|
||||||
|
* Fund Sources in the system
|
||||||
|
**/
|
||||||
|
Set<Long> existingPaymentTypes = new HashSet<Long>();
|
||||||
|
if (paymentChannelMappingArray != null) {
|
||||||
|
if (changes != null) {
|
||||||
|
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
|
||||||
|
command.jsonFragment(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < paymentChannelMappingArray.size(); i++) {
|
||||||
|
final JsonObject jsonObject = paymentChannelMappingArray.get(i).getAsJsonObject();
|
||||||
|
final Long paymentTypeId = jsonObject.get(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_TYPE.getValue()).getAsLong();
|
||||||
|
final Long paymentSpecificFundAccountId = jsonObject.get(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue()).getAsLong();
|
||||||
|
inputPaymentChannelFundSourceMap.put(paymentTypeId, paymentSpecificFundAccountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If input map is empty, delete all existing mappings
|
||||||
|
if (inputPaymentChannelFundSourceMap.size() == 0) {
|
||||||
|
accountMappingRepository.deleteInBatch(existingPaymentChannelToFundSourceMappings);
|
||||||
|
}/**
|
||||||
|
* Else, <br/>
|
||||||
|
* update existing mappings OR <br/>
|
||||||
|
* delete old mappings (which re already present, but not passed in
|
||||||
|
* as a part of Jsoncommand)<br/>
|
||||||
|
* Create new mappings for payment types that are passed in as a
|
||||||
|
* part of the Jsoncommand but not already present
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
else {
|
||||||
|
for (ProductToGLAccountMapping existingPaymentChannelToFundSourceMapping : existingPaymentChannelToFundSourceMappings) {
|
||||||
|
Long currentPaymentChannelId = existingPaymentChannelToFundSourceMapping.getPaymentType().getId();
|
||||||
|
existingPaymentTypes.add(currentPaymentChannelId);
|
||||||
|
// update existing mappings (if required)
|
||||||
|
if (inputPaymentChannelFundSourceMap.containsKey(currentPaymentChannelId)) {
|
||||||
|
Long newGLAccountId = inputPaymentChannelFundSourceMap.get(currentPaymentChannelId);
|
||||||
|
if (newGLAccountId != existingPaymentChannelToFundSourceMapping.getGlAccount().getId()) {
|
||||||
|
final GLAccount glAccount = getAccountByIdAndType(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(),
|
||||||
|
GLAccountType.ASSET, newGLAccountId);
|
||||||
|
existingPaymentChannelToFundSourceMapping.setGlAccount(glAccount);
|
||||||
|
accountMappingRepository.save(existingPaymentChannelToFundSourceMapping);
|
||||||
|
}
|
||||||
|
}// deleted payment type
|
||||||
|
else {
|
||||||
|
accountMappingRepository.delete(existingPaymentChannelToFundSourceMapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// create new mappings
|
||||||
|
Set<Long> incomingPaymentTypes = inputPaymentChannelFundSourceMap.keySet();
|
||||||
|
incomingPaymentTypes.removeAll(existingPaymentTypes);
|
||||||
|
// incomingPaymentTypes now only contains the newly added
|
||||||
|
// payment Type mappings
|
||||||
|
for (Long newPaymentType : incomingPaymentTypes) {
|
||||||
|
Long newGLAccountId = inputPaymentChannelFundSourceMap.get(newPaymentType);
|
||||||
|
savePaymentChannelToFundSourceMapping(productId, newPaymentType, newGLAccountId, portfolioProductType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param productId
|
||||||
|
* @param jsonObject
|
||||||
|
*/
|
||||||
|
private void savePaymentChannelToFundSourceMapping(final Long productId, final Long paymentTypeId,
|
||||||
|
final Long paymentTypeSpecificFundAccountId, final PortfolioProductType portfolioProductType) {
|
||||||
|
CodeValue paymentType = codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection(
|
||||||
|
PaymentDetailConstants.paymentTypeCodeName, paymentTypeId);
|
||||||
|
final GLAccount glAccount = getAccountByIdAndType(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), GLAccountType.ASSET,
|
||||||
|
paymentTypeSpecificFundAccountId);
|
||||||
|
final ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping(glAccount, productId,
|
||||||
|
portfolioProductType.getValue(), CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue(), paymentType);
|
||||||
|
this.accountMappingRepository.save(accountMapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches account with a particular Id and throws and Exception it is not
|
||||||
|
* of the expected Account Category ('ASSET','liability' etc)
|
||||||
|
*
|
||||||
|
* @param paramName
|
||||||
|
* @param expectedAccountType
|
||||||
|
* @param accountId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public GLAccount getAccountByIdAndType(final String paramName, final GLAccountType expectedAccountType, final Long accountId) {
|
||||||
|
final GLAccount glAccount = this.accountRepository.findOne(accountId);
|
||||||
|
if (glAccount == null) { throw new GLAccountNotFoundException(accountId); }
|
||||||
|
|
||||||
|
// validate account is of the expected Type
|
||||||
|
if (glAccount.getType().intValue() != expectedAccountType.getValue()) { throw new ProductToGLAccountMappingInvalidException(
|
||||||
|
paramName, glAccount.getName(), accountId, GLAccountType.fromInt(glAccount.getType()).toString(),
|
||||||
|
expectedAccountType.toString()); }
|
||||||
|
return glAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteProductToGLAccountMapping(final Long loanProductId, final PortfolioProductType portfolioProductType) {
|
||||||
|
final List<ProductToGLAccountMapping> productToGLAccountMappings = this.accountMappingRepository.findByProductIdAndProductType(
|
||||||
|
loanProductId, portfolioProductType.getValue());
|
||||||
|
if (productToGLAccountMappings != null && productToGLAccountMappings.size() > 0) {
|
||||||
|
this.accountMappingRepository.deleteInBatch(productToGLAccountMappings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-2
@@ -12,7 +12,11 @@ import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGL
|
|||||||
|
|
||||||
public interface ProductToGLAccountMappingReadPlatformService {
|
public interface ProductToGLAccountMappingReadPlatformService {
|
||||||
|
|
||||||
Map<String, Object> fetchAccountMappingDetailsForLoanProduct(final Long loanProductId, final Integer accountingType);
|
public Map<String, Object> fetchAccountMappingDetailsForLoanProduct(final Long loanProductId, final Integer accountingType);
|
||||||
|
|
||||||
List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForLoanProduct(final Long loanProductId);
|
public List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForLoanProduct(final Long loanProductId);
|
||||||
|
|
||||||
|
public Map<String, Object> fetchAccountMappingDetailsForSavingsProduct(final Long savingsProductId, final Integer accountingType);
|
||||||
|
|
||||||
|
public List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForSavingsProduct(final Long savingsProductId);
|
||||||
}
|
}
|
||||||
+61
-8
@@ -14,10 +14,13 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.mifosplatform.accounting.common.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN;
|
import org.mifosplatform.accounting.common.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN;
|
||||||
import org.mifosplatform.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
|
import org.mifosplatform.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_SAVINGS;
|
||||||
import org.mifosplatform.accounting.common.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
|
import org.mifosplatform.accounting.common.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.SAVINGS_PRODUCT_ACCOUNTING_PARAMS;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingRuleType;
|
||||||
import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.AccountingRuleType;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
@@ -33,11 +36,11 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class LoanProductToGLAccountMappingMapper implements RowMapper<Map<String, Object>> {
|
private static final class ProductToGLAccountMappingMapper implements RowMapper<Map<String, Object>> {
|
||||||
|
|
||||||
public String schema() {
|
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,"
|
return " id as id, gl_account_id as glAccountId,product_id as productId,product_type as productType,financial_account_type as financialAccountType,"
|
||||||
+ " payment_type as paymentTypeId from acc_product_mapping " + " where product_type=1 ";
|
+ " payment_type as paymentTypeId from acc_product_mapping " + " where product_type= ? ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -67,10 +70,11 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
|
|
||||||
final Map<String, Object> accountMappingDetails = new LinkedHashMap<String, Object>(8);
|
final Map<String, Object> accountMappingDetails = new LinkedHashMap<String, Object>(8);
|
||||||
|
|
||||||
final LoanProductToGLAccountMappingMapper rm = new LoanProductToGLAccountMappingMapper();
|
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
|
||||||
final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is null ";
|
final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is null ";
|
||||||
|
|
||||||
final List<Map<String, Object>> listOfProductToGLAccountMaps = this.jdbcTemplate.query(sql, rm, new Object[] { loanProductId });
|
final List<Map<String, Object>> listOfProductToGLAccountMaps = this.jdbcTemplate.query(sql, rm, new Object[] {
|
||||||
|
PortfolioProductType.LOAN.getValue(), loanProductId });
|
||||||
|
|
||||||
if (AccountingRuleType.CASH_BASED.getValue().equals(accountingType)) {
|
if (AccountingRuleType.CASH_BASED.getValue().equals(accountingType)) {
|
||||||
|
|
||||||
@@ -129,15 +133,63 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
return accountMappingDetails;
|
return accountMappingDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> fetchAccountMappingDetailsForSavingsProduct(Long savingsProductId, Integer accountingType) {
|
||||||
|
final Map<String, Object> accountMappingDetails = new LinkedHashMap<String, Object>(8);
|
||||||
|
|
||||||
|
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
|
||||||
|
final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is null ";
|
||||||
|
|
||||||
|
final List<Map<String, Object>> listOfProductToGLAccountMaps = this.jdbcTemplate.query(sql, rm, new Object[] {
|
||||||
|
PortfolioProductType.SAVING.getValue(), savingsProductId });
|
||||||
|
|
||||||
|
if (AccountingRuleType.CASH_BASED.getValue().equals(accountingType)) {
|
||||||
|
|
||||||
|
for (final Map<String, Object> productToGLAccountMap : listOfProductToGLAccountMaps) {
|
||||||
|
|
||||||
|
final Integer financialAccountType = (Integer) productToGLAccountMap.get("financialAccountType");
|
||||||
|
final CASH_ACCOUNTS_FOR_SAVINGS glAccountForSavings = CASH_ACCOUNTS_FOR_SAVINGS.fromInt(financialAccountType);
|
||||||
|
|
||||||
|
final Long glAccountId = (Long) productToGLAccountMap.get("glAccountId");
|
||||||
|
|
||||||
|
if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_REFERENCE)) {
|
||||||
|
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(), glAccountId);
|
||||||
|
} else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL)) {
|
||||||
|
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), glAccountId);
|
||||||
|
} else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_FEES)) {
|
||||||
|
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), glAccountId);
|
||||||
|
} else if (glAccountForSavings.equals(CASH_ACCOUNTS_FOR_SAVINGS.INTEREST_ON_SAVINGS)) {
|
||||||
|
accountMappingDetails.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), glAccountId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return accountMappingDetails;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForLoanProduct(Long loanProductId) {
|
public List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForLoanProduct(Long loanProductId) {
|
||||||
List<PaymentTypeToGLAccountMapper> paymentTypeToGLAccountMappers = null;
|
List<PaymentTypeToGLAccountMapper> paymentTypeToGLAccountMappers = null;
|
||||||
|
return fetchPaymentTypeToFundSourceMappings(PortfolioProductType.LOAN, loanProductId, paymentTypeToGLAccountMappers);
|
||||||
|
}
|
||||||
|
|
||||||
final LoanProductToGLAccountMappingMapper rm = new LoanProductToGLAccountMappingMapper();
|
@Override
|
||||||
|
public List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappingsForSavingsProduct(Long savingsProductId) {
|
||||||
|
List<PaymentTypeToGLAccountMapper> paymentTypeToGLAccountMappers = null;
|
||||||
|
return fetchPaymentTypeToFundSourceMappings(PortfolioProductType.SAVING, savingsProductId, paymentTypeToGLAccountMappers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param loanProductId
|
||||||
|
* @param paymentTypeToGLAccountMappers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private List<PaymentTypeToGLAccountMapper> fetchPaymentTypeToFundSourceMappings(PortfolioProductType portfolioProductType,
|
||||||
|
Long loanProductId, List<PaymentTypeToGLAccountMapper> paymentTypeToGLAccountMappers) {
|
||||||
|
final ProductToGLAccountMappingMapper rm = new ProductToGLAccountMappingMapper();
|
||||||
final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is not null";
|
final String sql = "select " + rm.schema() + " and product_id = ? and payment_type is not null";
|
||||||
|
|
||||||
final List<Map<String, Object>> paymentTypeToFundSourceMappingsList = this.jdbcTemplate.query(sql, rm,
|
final List<Map<String, Object>> paymentTypeToFundSourceMappingsList = this.jdbcTemplate.query(sql, rm, new Object[] {
|
||||||
new Object[] { loanProductId });
|
portfolioProductType.getValue(), loanProductId });
|
||||||
|
|
||||||
for (final Map<String, Object> productToGLAccountMap : paymentTypeToFundSourceMappingsList) {
|
for (final Map<String, Object> productToGLAccountMap : paymentTypeToFundSourceMappingsList) {
|
||||||
if (paymentTypeToGLAccountMappers == null) {
|
if (paymentTypeToGLAccountMappers == null) {
|
||||||
@@ -150,4 +202,5 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
|
|||||||
}
|
}
|
||||||
return paymentTypeToGLAccountMappers;
|
return paymentTypeToGLAccountMappers;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+5
-1
@@ -13,8 +13,12 @@ public interface ProductToGLAccountMappingWritePlatformService {
|
|||||||
|
|
||||||
void createLoanProductToGLAccountMapping(Long loanProductId, JsonCommand command);
|
void createLoanProductToGLAccountMapping(Long loanProductId, JsonCommand command);
|
||||||
|
|
||||||
|
void createSavingProductToGLAccountMapping(Long savingProductId, JsonCommand command);
|
||||||
|
|
||||||
Map<String, Object> updateLoanProductToGLAccountMapping(Long loanProductId, JsonCommand command, boolean accountingRuleChanged,
|
Map<String, Object> updateLoanProductToGLAccountMapping(Long loanProductId, JsonCommand command, boolean accountingRuleChanged,
|
||||||
int accountingRuleTypeId);
|
int accountingRuleTypeId);
|
||||||
|
|
||||||
void deleteLoanProductToGLAccountMapping(Long loanProductId);
|
Map<String, Object> updateSavingsProductToGLAccountMapping(Long savingsProductId, JsonCommand command, boolean accountingRuleChanged,
|
||||||
|
int accountingRuleTypeId);
|
||||||
|
|
||||||
}
|
}
|
||||||
+122
-464
@@ -6,57 +6,42 @@
|
|||||||
package org.mifosplatform.accounting.producttoaccountmapping.service;
|
package org.mifosplatform.accounting.producttoaccountmapping.service;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.common.AccountingRuleType;
|
||||||
import org.mifosplatform.accounting.common.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN;
|
import org.mifosplatform.accounting.common.AccountingConstants.ACCRUAL_ACCOUNTS_FOR_LOAN;
|
||||||
import org.mifosplatform.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
|
import org.mifosplatform.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_LOAN;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_SAVINGS;
|
||||||
import org.mifosplatform.accounting.common.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
|
import org.mifosplatform.accounting.common.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
|
||||||
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
|
import org.mifosplatform.accounting.common.AccountingConstants.SAVINGS_PRODUCT_ACCOUNTING_PARAMS;
|
||||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountRepository;
|
|
||||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
|
||||||
import org.mifosplatform.accounting.glaccount.exception.GLAccountNotFoundException;
|
|
||||||
import org.mifosplatform.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
|
||||||
import org.mifosplatform.accounting.producttoaccountmapping.domain.ProductToGLAccountMapping;
|
|
||||||
import org.mifosplatform.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
|
||||||
import org.mifosplatform.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingInvalidException;
|
|
||||||
import org.mifosplatform.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingNotFoundException;
|
|
||||||
import org.mifosplatform.accounting.producttoaccountmapping.serialization.ProductToGLAccountMappingFromApiJsonDeserializer;
|
import org.mifosplatform.accounting.producttoaccountmapping.serialization.ProductToGLAccountMappingFromApiJsonDeserializer;
|
||||||
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
|
|
||||||
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper;
|
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.AccountingRuleType;
|
|
||||||
import org.mifosplatform.portfolio.paymentdetail.PaymentDetailConstants;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.*;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class ProductToGLAccountMappingWritePlatformServiceImpl implements ProductToGLAccountMappingWritePlatformService {
|
public class ProductToGLAccountMappingWritePlatformServiceImpl implements ProductToGLAccountMappingWritePlatformService {
|
||||||
|
|
||||||
private final GLAccountRepository accountRepository;
|
|
||||||
private final ProductToGLAccountMappingRepository accountMappingRepository;
|
|
||||||
private final FromJsonHelper fromApiJsonHelper;
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
private final ProductToGLAccountMappingFromApiJsonDeserializer deserializer;
|
private final ProductToGLAccountMappingFromApiJsonDeserializer deserializer;
|
||||||
private final CodeValueRepositoryWrapper codeValueRepositoryWrapper;
|
private final LoanProductToGLAccountMappingHelper loanProductToGLAccountMappingHelper;
|
||||||
|
private final SavingsProductToGLAccountMappingHelper savingsProductToGLAccountMappingHelper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ProductToGLAccountMappingWritePlatformServiceImpl(final GLAccountRepository glAccountRepository,
|
public ProductToGLAccountMappingWritePlatformServiceImpl(final FromJsonHelper fromApiJsonHelper,
|
||||||
final ProductToGLAccountMappingRepository glAccountMappingRepository, final FromJsonHelper fromApiJsonHelper,
|
final ProductToGLAccountMappingFromApiJsonDeserializer deserializer,
|
||||||
final ProductToGLAccountMappingFromApiJsonDeserializer deserializer, final CodeValueRepositoryWrapper codeValueRepositoryWrapper) {
|
LoanProductToGLAccountMappingHelper loanProductToGLAccountMappingHelper,
|
||||||
this.accountRepository = glAccountRepository;
|
SavingsProductToGLAccountMappingHelper savingsProductToGLAccountMappingHelper) {
|
||||||
this.accountMappingRepository = glAccountMappingRepository;
|
|
||||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
this.deserializer = deserializer;
|
this.deserializer = deserializer;
|
||||||
this.codeValueRepositoryWrapper = codeValueRepositoryWrapper;
|
this.loanProductToGLAccountMappingHelper = loanProductToGLAccountMappingHelper;
|
||||||
|
this.savingsProductToGLAccountMappingHelper = savingsProductToGLAccountMappingHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -71,58 +56,115 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
|
|||||||
break;
|
break;
|
||||||
case CASH_BASED:
|
case CASH_BASED:
|
||||||
// asset
|
// asset
|
||||||
saveLoanToAssetAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper
|
||||||
CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue());
|
.saveLoanToAssetAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), loanProductId,
|
||||||
saveLoanToAssetAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), loanProductId,
|
CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue());
|
||||||
|
loanProductToGLAccountMappingHelper.saveLoanToAssetAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), loanProductId,
|
||||||
CASH_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.getValue());
|
CASH_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.getValue());
|
||||||
|
|
||||||
// income
|
// income
|
||||||
saveLoanToIncomeAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper.saveLoanToIncomeAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), loanProductId,
|
||||||
CASH_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.getValue());
|
CASH_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.getValue());
|
||||||
saveLoanToIncomeAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper.saveLoanToIncomeAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), loanProductId,
|
||||||
CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue());
|
CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue());
|
||||||
saveLoanToIncomeAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper.saveLoanToIncomeAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), loanProductId,
|
||||||
CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue());
|
CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue());
|
||||||
|
|
||||||
// expenses
|
// expenses
|
||||||
saveLoanToExpenseAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper.saveLoanToExpenseAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), loanProductId,
|
||||||
CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue());
|
CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue());
|
||||||
|
|
||||||
// advanced accounting mappings
|
// advanced accounting mappings
|
||||||
savePaymentChannelToFundSourceMappings(command, element, loanProductId, null);
|
loanProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, loanProductId, null);
|
||||||
break;
|
break;
|
||||||
case ACCRUAL_BASED:
|
case ACCRUAL_BASED:
|
||||||
|
|
||||||
// assets (including receivables)
|
// assets (including receivables)
|
||||||
saveLoanToAssetAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper.saveLoanToAssetAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), loanProductId,
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue());
|
ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue());
|
||||||
saveLoanToAssetAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper.saveLoanToAssetAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), loanProductId,
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.getValue());
|
ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.getValue());
|
||||||
saveLoanToAssetAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper.saveLoanToAssetAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(), loanProductId,
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE.getValue());
|
ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE.getValue());
|
||||||
saveLoanToAssetAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper.saveLoanToAssetAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), loanProductId,
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE.getValue());
|
ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE.getValue());
|
||||||
saveLoanToAssetAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper.saveLoanToAssetAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(), loanProductId,
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE.getValue());
|
ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE.getValue());
|
||||||
|
|
||||||
// income
|
// income
|
||||||
saveLoanToIncomeAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper.saveLoanToIncomeAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), loanProductId,
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.getValue());
|
ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.getValue());
|
||||||
saveLoanToIncomeAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper.saveLoanToIncomeAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), loanProductId,
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue());
|
ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue());
|
||||||
saveLoanToIncomeAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper.saveLoanToIncomeAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), loanProductId,
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue());
|
ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue());
|
||||||
|
|
||||||
// expenses
|
// expenses
|
||||||
saveLoanToExpenseAccountMapping(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), loanProductId,
|
loanProductToGLAccountMappingHelper.saveLoanToExpenseAccountMapping(element,
|
||||||
|
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), loanProductId,
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue());
|
ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue());
|
||||||
|
|
||||||
// advanced accounting mappings
|
// advanced accounting mappings
|
||||||
savePaymentChannelToFundSourceMappings(command, element, loanProductId, null);
|
loanProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, loanProductId, null);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void createSavingProductToGLAccountMapping(Long savingProductId, JsonCommand command) {
|
||||||
|
final JsonElement element = this.fromApiJsonHelper.parse(command.json());
|
||||||
|
final Integer accountingRuleTypeId = this.fromApiJsonHelper.extractIntegerNamed(accountingRuleParamName, element,
|
||||||
|
Locale.getDefault());
|
||||||
|
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(accountingRuleTypeId);
|
||||||
|
|
||||||
|
switch (accountingRuleType) {
|
||||||
|
case NONE:
|
||||||
|
break;
|
||||||
|
case CASH_BASED:
|
||||||
|
// asset
|
||||||
|
savingsProductToGLAccountMappingHelper.saveSavingsToAssetAccountMapping(element,
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(), savingProductId,
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_REFERENCE.getValue());
|
||||||
|
|
||||||
|
// income
|
||||||
|
savingsProductToGLAccountMappingHelper.saveSavingsToIncomeAccountMapping(element,
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), savingProductId,
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_FEES.getValue());
|
||||||
|
|
||||||
|
// expenses
|
||||||
|
savingsProductToGLAccountMappingHelper.saveSavingsToExpenseAccountMapping(element,
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), savingProductId,
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.INTEREST_ON_SAVINGS.getValue());
|
||||||
|
|
||||||
|
// liability
|
||||||
|
savingsProductToGLAccountMappingHelper.saveSavingsToLiabilityAccountMapping(element,
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), savingProductId,
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL.getValue());
|
||||||
|
|
||||||
|
// advanced accounting mappings
|
||||||
|
savingsProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, savingProductId, null);
|
||||||
|
break;
|
||||||
|
/*** Do not have accrual based accounting for now ***/
|
||||||
|
case ACCRUAL_BASED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public Map<String, Object> updateLoanProductToGLAccountMapping(final Long loanProductId, final JsonCommand command,
|
public Map<String, Object> updateLoanProductToGLAccountMapping(final Long loanProductId, final JsonCommand command,
|
||||||
@@ -131,7 +173,7 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
|
|||||||
* Variable tracks all accounting mapping properties that have been
|
* Variable tracks all accounting mapping properties that have been
|
||||||
* updated
|
* updated
|
||||||
***/
|
***/
|
||||||
final Map<String, Object> changes = new HashMap<String, Object>();
|
Map<String, Object> changes = new HashMap<String, Object>();
|
||||||
final JsonElement element = this.fromApiJsonHelper.parse(command.json());
|
final JsonElement element = this.fromApiJsonHelper.parse(command.json());
|
||||||
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(accountingRuleTypeId);
|
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(accountingRuleTypeId);
|
||||||
|
|
||||||
@@ -140,433 +182,49 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
|
|||||||
* for the product and recreate a new set of mappings
|
* for the product and recreate a new set of mappings
|
||||||
***/
|
***/
|
||||||
if (accountingRuleChanged) {
|
if (accountingRuleChanged) {
|
||||||
this.deserializer.validateForCreate(command.json());
|
this.deserializer.validateForLoanProductCreate(command.json());
|
||||||
handleChangesToAccountingRuleType(loanProductId, command, changes, element, accountingRuleType);
|
loanProductToGLAccountMappingHelper.deleteLoanProductToGLAccountMapping(loanProductId);
|
||||||
savePaymentChannelToFundSourceMappings(command, element, loanProductId, changes);
|
createLoanProductToGLAccountMapping(loanProductId, command);
|
||||||
|
changes = loanProductToGLAccountMappingHelper.populateChangesForNewLoanProductToGLAccountMappingCreation(element,
|
||||||
|
accountingRuleType);
|
||||||
|
loanProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, loanProductId, changes);
|
||||||
}/*** else examine and update individual changes ***/
|
}/*** else examine and update individual changes ***/
|
||||||
else {
|
else {
|
||||||
handleChangesToLoanProductToGLAccountMappings(loanProductId, changes, element, accountingRuleType);
|
loanProductToGLAccountMappingHelper.handleChangesToLoanProductToGLAccountMappings(loanProductId, changes, element,
|
||||||
updatePaymentChannelToFundSourceMappings(command, element, loanProductId, changes);
|
accountingRuleType);
|
||||||
|
loanProductToGLAccountMappingHelper.updatePaymentChannelToFundSourceMappings(command, element, loanProductId, changes);
|
||||||
}
|
}
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteLoanProductToGLAccountMapping(final Long loanProductId) {
|
public Map<String, Object> updateSavingsProductToGLAccountMapping(Long savingsProductId, JsonCommand command,
|
||||||
final List<ProductToGLAccountMapping> productToGLAccountMappings = this.accountMappingRepository.findByProductIdAndProductType(
|
boolean accountingRuleChanged, int accountingRuleTypeId) {
|
||||||
loanProductId, PortfolioProductType.LOAN.getValue());
|
|
||||||
if (productToGLAccountMappings != null && productToGLAccountMappings.size() > 0) {
|
|
||||||
this.accountMappingRepository.deleteInBatch(productToGLAccountMappings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves payment type to Fund source mappings (also populates the changes
|
|
||||||
* array if passed in)
|
|
||||||
*
|
|
||||||
* @param command
|
|
||||||
* @param element
|
|
||||||
* @param productId
|
|
||||||
* @param changes
|
|
||||||
*/
|
|
||||||
private void savePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
|
||||||
Map<String, Object> changes) {
|
|
||||||
JsonArray paymentChannelMappingArray = fromApiJsonHelper.extractJsonArrayNamed(
|
|
||||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element);
|
|
||||||
if (paymentChannelMappingArray != null) {
|
|
||||||
if (changes != null) {
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
|
|
||||||
command.jsonFragment(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue()));
|
|
||||||
}
|
|
||||||
for (int i = 0; i < paymentChannelMappingArray.size(); i++) {
|
|
||||||
final JsonObject jsonObject = paymentChannelMappingArray.get(i).getAsJsonObject();
|
|
||||||
final Long paymentTypeId = jsonObject.get(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_TYPE.getValue()).getAsLong();
|
|
||||||
final Long paymentSpecificFundAccountId = jsonObject.get(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue()).getAsLong();
|
|
||||||
savePaymentChannelToFundSourceMapping(productId, paymentTypeId, paymentSpecificFundAccountId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param command
|
|
||||||
* @param element
|
|
||||||
* @param productId
|
|
||||||
* @param changes
|
|
||||||
*/
|
|
||||||
private void updatePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
|
||||||
Map<String, Object> changes) {
|
|
||||||
// find all existing payment Channel to Fund source Mappings
|
|
||||||
List<ProductToGLAccountMapping> existingPaymentChannelToFundSourceMappings = accountMappingRepository
|
|
||||||
.findAllPaymentTypeToFundSourceMappings(productId, PortfolioProductType.LOAN.getValue());
|
|
||||||
JsonArray paymentChannelMappingArray = fromApiJsonHelper.extractJsonArrayNamed(
|
|
||||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element);
|
|
||||||
/**
|
|
||||||
* Variable stores a map representation of Payment channels (key) and
|
|
||||||
* their fund sources (value) extracted from the passed in Jsoncommand
|
|
||||||
**/
|
|
||||||
Map<Long, Long> inputPaymentChannelFundSourceMap = new HashMap<Long, Long>();
|
|
||||||
/***
|
/***
|
||||||
* Variable stores all payment types which hae already been mapped to
|
* Variable tracks all accounting mapping properties that have been
|
||||||
* Fund Sources in the system
|
* updated
|
||||||
**/
|
***/
|
||||||
Set<Long> existingPaymentTypes = new HashSet<Long>();
|
Map<String, Object> changes = new HashMap<String, Object>();
|
||||||
if (paymentChannelMappingArray != null) {
|
final JsonElement element = this.fromApiJsonHelper.parse(command.json());
|
||||||
if (changes != null) {
|
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(accountingRuleTypeId);
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
|
|
||||||
command.jsonFragment(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < paymentChannelMappingArray.size(); i++) {
|
/***
|
||||||
final JsonObject jsonObject = paymentChannelMappingArray.get(i).getAsJsonObject();
|
* If the accounting rule has been changed, delete all existing mapping
|
||||||
final Long paymentTypeId = jsonObject.get(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_TYPE.getValue()).getAsLong();
|
* for the product and recreate a new set of mappings
|
||||||
final Long paymentSpecificFundAccountId = jsonObject.get(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue()).getAsLong();
|
***/
|
||||||
inputPaymentChannelFundSourceMap.put(paymentTypeId, paymentSpecificFundAccountId);
|
if (accountingRuleChanged) {
|
||||||
}
|
this.deserializer.validateForSavingsProductCreate(command.json());
|
||||||
|
savingsProductToGLAccountMappingHelper.deleteSavingsProductToGLAccountMapping(savingsProductId);
|
||||||
// If input map is empty, delete all existing mappings
|
createSavingProductToGLAccountMapping(savingsProductId, command);
|
||||||
if (inputPaymentChannelFundSourceMap.size() == 0) {
|
changes = savingsProductToGLAccountMappingHelper.populateChangesForNewSavingsProductToGLAccountMappingCreation(element,
|
||||||
accountMappingRepository.deleteInBatch(existingPaymentChannelToFundSourceMappings);
|
accountingRuleType);
|
||||||
}/**
|
savingsProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, savingsProductId, changes);
|
||||||
* Else, <br/>
|
}/*** else examine and update individual changes ***/
|
||||||
* update existing mappings OR <br/>
|
else {
|
||||||
* delete old mappings (which re already present, but not passed in
|
savingsProductToGLAccountMappingHelper.handleChangesToSavingsProductToGLAccountMappings(savingsProductId, changes, element,
|
||||||
* as a part of Jsoncommand)<br/>
|
accountingRuleType);
|
||||||
* Create new mappings for payment types that are passed in as a
|
savingsProductToGLAccountMappingHelper.updatePaymentChannelToFundSourceMappings(command, element, savingsProductId, changes);
|
||||||
* part of the Jsoncommand but not already present
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
else {
|
|
||||||
for (ProductToGLAccountMapping existingPaymentChannelToFundSourceMapping : existingPaymentChannelToFundSourceMappings) {
|
|
||||||
Long currentPaymentChannelId = existingPaymentChannelToFundSourceMapping.getPaymentType().getId();
|
|
||||||
existingPaymentTypes.add(currentPaymentChannelId);
|
|
||||||
// update existing mappings (if required)
|
|
||||||
if (inputPaymentChannelFundSourceMap.containsKey(currentPaymentChannelId)) {
|
|
||||||
Long newGLAccountId = inputPaymentChannelFundSourceMap.get(currentPaymentChannelId);
|
|
||||||
if (newGLAccountId != existingPaymentChannelToFundSourceMapping.getGlAccount().getId()) {
|
|
||||||
final GLAccount glAccount = getAccountByIdAndType(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(),
|
|
||||||
GLAccountType.ASSET, newGLAccountId);
|
|
||||||
existingPaymentChannelToFundSourceMapping.setGlAccount(glAccount);
|
|
||||||
accountMappingRepository.save(existingPaymentChannelToFundSourceMapping);
|
|
||||||
}
|
|
||||||
}// deleted payment type
|
|
||||||
else {
|
|
||||||
accountMappingRepository.delete(existingPaymentChannelToFundSourceMapping);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// create new mappings
|
|
||||||
Set<Long> incomingPaymentTypes = inputPaymentChannelFundSourceMap.keySet();
|
|
||||||
incomingPaymentTypes.removeAll(existingPaymentTypes);
|
|
||||||
// incomingPaymentTypes now only contains the newly added
|
|
||||||
// payment Type mappings
|
|
||||||
for (Long newPaymentType : incomingPaymentTypes) {
|
|
||||||
Long newGLAccountId = inputPaymentChannelFundSourceMap.get(newPaymentType);
|
|
||||||
savePaymentChannelToFundSourceMapping(productId, newPaymentType, newGLAccountId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param productId
|
|
||||||
* @param jsonObject
|
|
||||||
*/
|
|
||||||
private void savePaymentChannelToFundSourceMapping(final Long productId, final Long paymentTypeId,
|
|
||||||
final Long paymentTypeSpecificFundAccountId) {
|
|
||||||
CodeValue paymentType = codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection(
|
|
||||||
PaymentDetailConstants.paymentTypeCodeName, paymentTypeId);
|
|
||||||
final GLAccount glAccount = getAccountByIdAndType(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), GLAccountType.ASSET,
|
|
||||||
paymentTypeSpecificFundAccountId);
|
|
||||||
final ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping(glAccount, productId,
|
|
||||||
PortfolioProductType.LOAN.getValue(), CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue(), paymentType);
|
|
||||||
this.accountMappingRepository.save(accountMapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Examines and updates each account mapping for given loan product with
|
|
||||||
* changes passed in from the Json element
|
|
||||||
*
|
|
||||||
* @param loanProductId
|
|
||||||
* @param changes
|
|
||||||
* @param element
|
|
||||||
* @param accountingRuleType
|
|
||||||
*/
|
|
||||||
private void handleChangesToLoanProductToGLAccountMappings(final Long loanProductId, final Map<String, Object> changes,
|
|
||||||
final JsonElement element, final AccountingRuleType accountingRuleType) {
|
|
||||||
switch (accountingRuleType) {
|
|
||||||
case NONE:
|
|
||||||
break;
|
|
||||||
case CASH_BASED:
|
|
||||||
// asset
|
|
||||||
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), loanProductId,
|
|
||||||
CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue(), CASH_ACCOUNTS_FOR_LOAN.FUND_SOURCE.toString(), changes);
|
|
||||||
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), loanProductId,
|
|
||||||
CASH_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.getValue(), CASH_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.toString(), changes);
|
|
||||||
|
|
||||||
// income
|
|
||||||
mergeLoanToIncomeAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), loanProductId,
|
|
||||||
CASH_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.getValue(), CASH_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.toString(), changes);
|
|
||||||
mergeLoanToIncomeAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), loanProductId,
|
|
||||||
CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue(), CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.toString(), changes);
|
|
||||||
mergeLoanToIncomeAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(),
|
|
||||||
loanProductId, CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue(),
|
|
||||||
CASH_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.toString(), changes);
|
|
||||||
|
|
||||||
// expenses
|
|
||||||
mergeLoanToExpenseAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(),
|
|
||||||
loanProductId, CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue(),
|
|
||||||
CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.toString(), changes);
|
|
||||||
break;
|
|
||||||
case ACCRUAL_BASED:
|
|
||||||
// assets (including receivables)
|
|
||||||
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), loanProductId,
|
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE.toString(), changes);
|
|
||||||
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), loanProductId,
|
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO.toString(), changes);
|
|
||||||
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(),
|
|
||||||
loanProductId, ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE.getValue(),
|
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE.toString(), changes);
|
|
||||||
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), loanProductId,
|
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE.toString(), changes);
|
|
||||||
mergeLoanToAssetAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(),
|
|
||||||
loanProductId, ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE.getValue(),
|
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE.toString(), changes);
|
|
||||||
|
|
||||||
// income
|
|
||||||
mergeLoanToIncomeAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), loanProductId,
|
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS.toString(),
|
|
||||||
changes);
|
|
||||||
mergeLoanToIncomeAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), loanProductId,
|
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.toString(),
|
|
||||||
changes);
|
|
||||||
mergeLoanToIncomeAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(),
|
|
||||||
loanProductId, ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue(),
|
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.toString(), changes);
|
|
||||||
|
|
||||||
// expenses
|
|
||||||
mergeLoanToExpenseAccountMappingChanges(element, LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(),
|
|
||||||
loanProductId, ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.getValue(),
|
|
||||||
ACCRUAL_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF.toString(), changes);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* delete all existing mapping for a product and recreates a new set of
|
|
||||||
* mappings (to be used exclusively when the selected accounting rule has
|
|
||||||
* changed)
|
|
||||||
*
|
|
||||||
* @param loanProductId
|
|
||||||
* @param command
|
|
||||||
* @param changes
|
|
||||||
* @param element
|
|
||||||
* @param accountingRuleType
|
|
||||||
*/
|
|
||||||
private void handleChangesToAccountingRuleType(final Long loanProductId, final JsonCommand command, final Map<String, Object> changes,
|
|
||||||
final JsonElement element, final AccountingRuleType accountingRuleType) {
|
|
||||||
deleteLoanProductToGLAccountMapping(loanProductId);
|
|
||||||
createLoanProductToGLAccountMapping(loanProductId, command);
|
|
||||||
final Long fundAccountId = this.fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), element);
|
|
||||||
final Long loanPortfolioAccountId = this.fromApiJsonHelper.extractLongNamed(
|
|
||||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), element);
|
|
||||||
final Long incomeFromInterestId = this.fromApiJsonHelper.extractLongNamed(
|
|
||||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), element);
|
|
||||||
final Long incomeFromFeeId = this.fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
|
|
||||||
element);
|
|
||||||
final Long incomeFromPenaltyId = this.fromApiJsonHelper.extractLongNamed(
|
|
||||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), element);
|
|
||||||
final Long writeOffAccountId = this.fromApiJsonHelper.extractLongNamed(
|
|
||||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), element);
|
|
||||||
|
|
||||||
final Long receivableInterestAccountId = this.fromApiJsonHelper.extractLongNamed(
|
|
||||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(), element);
|
|
||||||
final Long receivableFeeAccountId = this.fromApiJsonHelper.extractLongNamed(
|
|
||||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), element);
|
|
||||||
final Long receivablePenaltyAccountId = this.fromApiJsonHelper.extractLongNamed(
|
|
||||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(), element);
|
|
||||||
|
|
||||||
switch (accountingRuleType) {
|
|
||||||
case NONE:
|
|
||||||
break;
|
|
||||||
case CASH_BASED:
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), fundAccountId);
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), loanPortfolioAccountId);
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), incomeFromInterestId);
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), incomeFromFeeId);
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), incomeFromPenaltyId);
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), writeOffAccountId);
|
|
||||||
break;
|
|
||||||
case ACCRUAL_BASED:
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), fundAccountId);
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), loanPortfolioAccountId);
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), incomeFromInterestId);
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), incomeFromFeeId);
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), incomeFromPenaltyId);
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), writeOffAccountId);
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(), receivableInterestAccountId);
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), receivableFeeAccountId);
|
|
||||||
changes.put(LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(), receivablePenaltyAccountId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility wrapper for
|
|
||||||
* {@link #saveLoanToAccountMapping(JsonElement, String, Long, int, GLAccountType)}
|
|
||||||
*
|
|
||||||
* @param element
|
|
||||||
* @param paramName
|
|
||||||
* @param productId
|
|
||||||
* @param placeHolderTypeId
|
|
||||||
*/
|
|
||||||
private void saveLoanToAssetAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
|
||||||
final int placeHolderTypeId) {
|
|
||||||
saveLoanToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.ASSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility wrapper for
|
|
||||||
* {@link #saveLoanToAccountMapping(JsonElement, String, Long, int, GLAccountType)}
|
|
||||||
*
|
|
||||||
* @param element
|
|
||||||
* @param paramName
|
|
||||||
* @param productId
|
|
||||||
* @param placeHolderTypeId
|
|
||||||
*/
|
|
||||||
private void saveLoanToIncomeAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
|
||||||
final int placeHolderTypeId) {
|
|
||||||
saveLoanToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.INCOME);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility wrapper for
|
|
||||||
* {@link #saveLoanToAccountMapping(JsonElement, String, Long, int, GLAccountType)}
|
|
||||||
*
|
|
||||||
* @param element
|
|
||||||
* @param paramName
|
|
||||||
* @param productId
|
|
||||||
* @param placeHolderTypeId
|
|
||||||
*/
|
|
||||||
private void saveLoanToExpenseAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
|
||||||
final int placeHolderTypeId) {
|
|
||||||
saveLoanToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.EXPENSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param element
|
|
||||||
* @param paramName
|
|
||||||
* @param productId
|
|
||||||
* @param placeHolderTypeId
|
|
||||||
* @param expectedAccountType
|
|
||||||
*/
|
|
||||||
private void saveLoanToAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
|
||||||
final int placeHolderTypeId, final GLAccountType expectedAccountType) {
|
|
||||||
final Long accountId = this.fromApiJsonHelper.extractLongNamed(paramName, element);
|
|
||||||
final GLAccount glAccount = getAccountByIdAndType(paramName, expectedAccountType, accountId);
|
|
||||||
|
|
||||||
final ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping(glAccount, productId,
|
|
||||||
PortfolioProductType.LOAN.getValue(), placeHolderTypeId);
|
|
||||||
this.accountMappingRepository.save(accountMapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility wrapper for
|
|
||||||
* {@link #mergeLoanToAccountMappingChanges(JsonElement, String, Long, int, String, Map, GLAccountType)}
|
|
||||||
*
|
|
||||||
* @param element
|
|
||||||
* @param paramName
|
|
||||||
* @param productId
|
|
||||||
* @param accountTypeId
|
|
||||||
* @param accountTypeName
|
|
||||||
* @param changes
|
|
||||||
*/
|
|
||||||
private void mergeLoanToAssetAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
|
||||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
|
||||||
mergeLoanToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.ASSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility wrapper for
|
|
||||||
* {@link #mergeLoanToAccountMappingChanges(JsonElement, String, Long, int, String, Map, GLAccountType)}
|
|
||||||
*
|
|
||||||
* @param element
|
|
||||||
* @param paramName
|
|
||||||
* @param productId
|
|
||||||
* @param accountTypeId
|
|
||||||
* @param accountTypeName
|
|
||||||
* @param changes
|
|
||||||
*/
|
|
||||||
private void mergeLoanToIncomeAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
|
||||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
|
||||||
mergeLoanToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.INCOME);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility wrapper for
|
|
||||||
* {@link #mergeLoanToAccountMappingChanges(JsonElement, String, Long, int, String, Map, GLAccountType)}
|
|
||||||
*
|
|
||||||
* @param element
|
|
||||||
* @param paramName
|
|
||||||
* @param productId
|
|
||||||
* @param accountTypeId
|
|
||||||
* @param accountTypeName
|
|
||||||
* @param changes
|
|
||||||
*/
|
|
||||||
private void mergeLoanToExpenseAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
|
||||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
|
||||||
mergeLoanToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.EXPENSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method merges changes passed in through JSON element
|
|
||||||
*
|
|
||||||
* @param element
|
|
||||||
* @param paramName
|
|
||||||
* @param productId
|
|
||||||
* @param accountTypeId
|
|
||||||
* @param accountTypeName
|
|
||||||
* @param changes
|
|
||||||
* @param expectedAccountType
|
|
||||||
*/
|
|
||||||
private void mergeLoanToAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
|
||||||
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes,
|
|
||||||
final GLAccountType expectedAccountType) {
|
|
||||||
final Long accountId = this.fromApiJsonHelper.extractLongNamed(paramName, element);
|
|
||||||
|
|
||||||
// get the existing product
|
|
||||||
if (accountId != null) {
|
|
||||||
final ProductToGLAccountMapping accountMapping = this.accountMappingRepository.findCoreProductToFinAccountMapping(productId,
|
|
||||||
PortfolioProductType.LOAN.getValue(), accountTypeId);
|
|
||||||
if (accountMapping == null) { throw new ProductToGLAccountMappingNotFoundException(PortfolioProductType.LOAN, productId,
|
|
||||||
accountTypeName); }
|
|
||||||
if (accountMapping.getGlAccount().getId() != accountId) {
|
|
||||||
final GLAccount glAccount = getAccountByIdAndType(paramName, expectedAccountType, accountId);
|
|
||||||
changes.put(paramName, accountId);
|
|
||||||
accountMapping.setGlAccount(glAccount);
|
|
||||||
this.accountMappingRepository.save(accountMapping);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches account with a particular Id and throws and Exception it is not
|
|
||||||
* of the expected Account Category ('ASSET','liability' etc)
|
|
||||||
*
|
|
||||||
* @param paramName
|
|
||||||
* @param expectedAccountType
|
|
||||||
* @param accountId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private GLAccount getAccountByIdAndType(final String paramName, final GLAccountType expectedAccountType, final Long accountId) {
|
|
||||||
final GLAccount glAccount = this.accountRepository.findOne(accountId);
|
|
||||||
if (glAccount == null) { throw new GLAccountNotFoundException(accountId); }
|
|
||||||
|
|
||||||
// validate account is of the expected Type
|
|
||||||
if (glAccount.getType().intValue() != expectedAccountType.getValue()) { throw new ProductToGLAccountMappingInvalidException(
|
|
||||||
paramName, glAccount.getName(), accountId, GLAccountType.fromInt(glAccount.getType()).toString(),
|
|
||||||
expectedAccountType.toString()); }
|
|
||||||
return glAccount;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+162
@@ -0,0 +1,162 @@
|
|||||||
|
package org.mifosplatform.accounting.producttoaccountmapping.service;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.common.AccountingRuleType;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.CASH_ACCOUNTS_FOR_SAVINGS;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.SAVINGS_PRODUCT_ACCOUNTING_PARAMS;
|
||||||
|
import org.mifosplatform.accounting.glaccount.domain.GLAccountRepository;
|
||||||
|
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||||
|
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SavingsProductToGLAccountMappingHelper extends ProductToGLAccountMappingHelper {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SavingsProductToGLAccountMappingHelper(GLAccountRepository glAccountRepository,
|
||||||
|
ProductToGLAccountMappingRepository glAccountMappingRepository, FromJsonHelper fromApiJsonHelper,
|
||||||
|
CodeValueRepositoryWrapper codeValueRepositoryWrapper) {
|
||||||
|
super(glAccountRepository, glAccountMappingRepository, fromApiJsonHelper, codeValueRepositoryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Set of abstractions for saving Saving Products to GL Account Mappings ***/
|
||||||
|
|
||||||
|
public void saveSavingsToAssetAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int placeHolderTypeId) {
|
||||||
|
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.ASSET, PortfolioProductType.SAVING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveSavingsToIncomeAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int placeHolderTypeId) {
|
||||||
|
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.INCOME, PortfolioProductType.SAVING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveSavingsToExpenseAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int placeHolderTypeId) {
|
||||||
|
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.EXPENSE, PortfolioProductType.SAVING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveSavingsToLiabilityAccountMapping(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int placeHolderTypeId) {
|
||||||
|
saveProductToAccountMapping(element, paramName, productId, placeHolderTypeId, GLAccountType.LIABILITY, PortfolioProductType.SAVING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Set of abstractions for merging Savings Products to GL Account Mappings ***/
|
||||||
|
|
||||||
|
public void mergeSavingsToAssetAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||||
|
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.ASSET,
|
||||||
|
PortfolioProductType.SAVING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mergeSavingsToIncomeAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||||
|
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.INCOME,
|
||||||
|
PortfolioProductType.SAVING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mergeSavingsToExpenseAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||||
|
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes, GLAccountType.EXPENSE,
|
||||||
|
PortfolioProductType.SAVING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mergeSavingsToLiabilityAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
|
||||||
|
final int accountTypeId, final String accountTypeName, final Map<String, Object> changes) {
|
||||||
|
mergeProductToAccountMappingChanges(element, paramName, productId, accountTypeId, accountTypeName, changes,
|
||||||
|
GLAccountType.LIABILITY, PortfolioProductType.SAVING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Abstractions for payments channel related to savings products ***/
|
||||||
|
|
||||||
|
public void savePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||||
|
Map<String, Object> changes) {
|
||||||
|
savePaymentChannelToFundSourceMappings(command, element, productId, changes, PortfolioProductType.SAVING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePaymentChannelToFundSourceMappings(final JsonCommand command, final JsonElement element, final Long productId,
|
||||||
|
Map<String, Object> changes) {
|
||||||
|
updatePaymentChannelToFundSourceMappings(command, element, productId, changes, PortfolioProductType.SAVING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> populateChangesForNewSavingsProductToGLAccountMappingCreation(final JsonElement element,
|
||||||
|
final AccountingRuleType accountingRuleType) {
|
||||||
|
final Map<String, Object> changes = new HashMap<String, Object>();
|
||||||
|
|
||||||
|
final Long savingsReferenceId = this.fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(), element);
|
||||||
|
final Long incomeFromFeesId = this.fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), element);
|
||||||
|
final Long interestOnSavingsId = this.fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
|
||||||
|
final Long savingsControlId = this.fromApiJsonHelper.extractLongNamed(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(),
|
||||||
|
element);
|
||||||
|
|
||||||
|
switch (accountingRuleType) {
|
||||||
|
case NONE:
|
||||||
|
break;
|
||||||
|
case CASH_BASED:
|
||||||
|
changes.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), savingsControlId);
|
||||||
|
changes.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(), savingsReferenceId);
|
||||||
|
changes.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), interestOnSavingsId);
|
||||||
|
changes.put(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), incomeFromFeesId);
|
||||||
|
break;
|
||||||
|
case ACCRUAL_BASED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Examines and updates each account mapping for given loan product with
|
||||||
|
* changes passed in from the Json element
|
||||||
|
*
|
||||||
|
* @param savingsProductId
|
||||||
|
* @param changes
|
||||||
|
* @param element
|
||||||
|
* @param accountingRuleType
|
||||||
|
*/
|
||||||
|
public void handleChangesToSavingsProductToGLAccountMappings(final Long savingsProductId, final Map<String, Object> changes,
|
||||||
|
final JsonElement element, final AccountingRuleType accountingRuleType) {
|
||||||
|
switch (accountingRuleType) {
|
||||||
|
case NONE:
|
||||||
|
break;
|
||||||
|
case CASH_BASED:
|
||||||
|
// asset
|
||||||
|
mergeSavingsToAssetAccountMappingChanges(element, SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(),
|
||||||
|
savingsProductId, CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_REFERENCE.getValue(),
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_REFERENCE.toString(), changes);
|
||||||
|
|
||||||
|
// income
|
||||||
|
mergeSavingsToIncomeAccountMappingChanges(element, SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
|
||||||
|
savingsProductId, CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_FEES.getValue(),
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.INCOME_FROM_FEES.toString(), changes);
|
||||||
|
|
||||||
|
// expenses
|
||||||
|
mergeSavingsToExpenseAccountMappingChanges(element, SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(),
|
||||||
|
savingsProductId, CASH_ACCOUNTS_FOR_SAVINGS.INTEREST_ON_SAVINGS.getValue(),
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.INTEREST_ON_SAVINGS.toString(), changes);
|
||||||
|
|
||||||
|
// liability
|
||||||
|
mergeSavingsToLiabilityAccountMappingChanges(element, SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(),
|
||||||
|
savingsProductId, CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL.getValue(),
|
||||||
|
CASH_ACCOUNTS_FOR_SAVINGS.SAVINGS_CONTROL.toString(), changes);
|
||||||
|
break;
|
||||||
|
case ACCRUAL_BASED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteSavingsProductToGLAccountMapping(final Long savingsProductId) {
|
||||||
|
deleteProductToGLAccountMapping(savingsProductId, PortfolioProductType.SAVING);
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-25
@@ -24,9 +24,8 @@ 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.accounting.common.AccountingDropdownReadPlatformService;
|
||||||
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||||
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
|
|
||||||
import org.mifosplatform.accounting.glaccount.service.GLAccountReadPlatformService;
|
|
||||||
import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
||||||
import org.mifosplatform.accounting.producttoaccountmapping.service.ProductToGLAccountMappingReadPlatformService;
|
import org.mifosplatform.accounting.producttoaccountmapping.service.ProductToGLAccountMappingReadPlatformService;
|
||||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||||
@@ -81,9 +80,9 @@ 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;
|
private final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService;
|
||||||
private final CodeValueReadPlatformService codeValueReadPlatformService;
|
private final CodeValueReadPlatformService codeValueReadPlatformService;
|
||||||
|
private final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanProductsApiResource(final PlatformSecurityContext context, final LoanProductReadPlatformService readPlatformService,
|
public LoanProductsApiResource(final PlatformSecurityContext context, final LoanProductReadPlatformService readPlatformService,
|
||||||
@@ -92,9 +91,9 @@ public class LoanProductsApiResource {
|
|||||||
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,
|
final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService,
|
||||||
final CodeValueReadPlatformService codeValueReadPlatformService) {
|
final CodeValueReadPlatformService codeValueReadPlatformService,
|
||||||
|
final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.loanProductReadPlatformService = readPlatformService;
|
this.loanProductReadPlatformService = readPlatformService;
|
||||||
this.chargeReadPlatformService = chargeReadPlatformService;
|
this.chargeReadPlatformService = chargeReadPlatformService;
|
||||||
@@ -104,9 +103,9 @@ 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;
|
this.accountMappingReadPlatformService = accountMappingReadPlatformService;
|
||||||
this.codeValueReadPlatformService = codeValueReadPlatformService;
|
this.codeValueReadPlatformService = codeValueReadPlatformService;
|
||||||
|
this.accountingDropdownReadPlatformService = accountingDropdownReadPlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@@ -218,26 +217,10 @@ public class LoanProductsApiResource {
|
|||||||
final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions = this.dropdownReadPlatformService
|
final Collection<TransactionProcessingStrategyData> transactionProcessingStrategyOptions = this.dropdownReadPlatformService
|
||||||
.retreiveTransactionProcessingStrategies();
|
.retreiveTransactionProcessingStrategies();
|
||||||
|
|
||||||
Map<String, List<GLAccountData>> accountOptions = new HashMap<String, List<GLAccountData>>();
|
Map<String, List<GLAccountData>> accountOptions = accountingDropdownReadPlatformService
|
||||||
List<GLAccountData> assetAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GLAccountType.ASSET);
|
.retrieveAccountMappingOptionsForLoanProducts();
|
||||||
if (assetAccountOptions.isEmpty()) {
|
|
||||||
assetAccountOptions = null;
|
|
||||||
}
|
|
||||||
accountOptions.put("assetAccountOptions", assetAccountOptions);
|
|
||||||
|
|
||||||
List<GLAccountData> incomeAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GLAccountType.INCOME);
|
List<EnumOptionData> accountingRuleTypeOptions = accountingDropdownReadPlatformService.retrieveAccountingRuleTypeOptions();
|
||||||
if (incomeAccountOptions.isEmpty()) {
|
|
||||||
incomeAccountOptions = null;
|
|
||||||
}
|
|
||||||
accountOptions.put("incomeAccountOptions", incomeAccountOptions);
|
|
||||||
|
|
||||||
List<GLAccountData> expenseAccountOptions = accountReadPlatformService.retrieveAllEnabledDetailGLAccounts(GLAccountType.EXPENSE);
|
|
||||||
if (expenseAccountOptions.isEmpty()) {
|
|
||||||
expenseAccountOptions = null;
|
|
||||||
}
|
|
||||||
accountOptions.put("expenseAccountOptions", expenseAccountOptions);
|
|
||||||
|
|
||||||
List<EnumOptionData> accountingRuleTypeOptions = dropdownReadPlatformService.retrieveAccountingRuleTypeOptions();
|
|
||||||
|
|
||||||
return new LoanProductData(productData, chargeOptions, paymentTypeOptions, currencyOptions, amortizationTypeOptions,
|
return new LoanProductData(productData, chargeOptions, paymentTypeOptions, currencyOptions, amortizationTypeOptions,
|
||||||
interestTypeOptions, interestCalculationPeriodTypeOptions, repaymentFrequencyTypeOptions, interestRateFrequencyTypeOptions,
|
interestTypeOptions, interestCalculationPeriodTypeOptions, repaymentFrequencyTypeOptions, interestRateFrequencyTypeOptions,
|
||||||
|
|||||||
+4
-3
@@ -11,6 +11,8 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.common.AccountingEnumerations;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingRuleType;
|
||||||
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||||
import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
||||||
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
||||||
@@ -18,7 +20,6 @@ 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;
|
||||||
import org.mifosplatform.portfolio.fund.data.FundData;
|
import org.mifosplatform.portfolio.fund.data.FundData;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.AccountingRuleType;
|
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
||||||
@@ -182,7 +183,7 @@ 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 EnumOptionData accountingType = LoanEnumerations.accountingRuleType(AccountingRuleType.NONE);
|
final EnumOptionData accountingType = AccountingEnumerations.accountingRuleType(AccountingRuleType.NONE);
|
||||||
|
|
||||||
return new LoanProductData(id, name, description, currency, principal, minPrincipal, maxPrincipal, tolerance, numberOfRepayments,
|
return new LoanProductData(id, name, description, currency, principal, minPrincipal, maxPrincipal, tolerance, numberOfRepayments,
|
||||||
minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod, minInterestRatePerPeriod,
|
minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod, minInterestRatePerPeriod,
|
||||||
@@ -346,7 +347,7 @@ public class LoanProductData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAccountingEnabled() {
|
public boolean hasAccountingEnabled() {
|
||||||
return this.accountingRule.getId() > 1;
|
return this.accountingRule.getId() > AccountingRuleType.NONE.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
|
|||||||
+1
@@ -22,6 +22,7 @@ import javax.persistence.Table;
|
|||||||
import javax.persistence.UniqueConstraint;
|
import javax.persistence.UniqueConstraint;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingRuleType;
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
|
|||||||
+1
-1
@@ -16,13 +16,13 @@ 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.common.AccountingRuleType;
|
||||||
import org.mifosplatform.accounting.common.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
|
import org.mifosplatform.accounting.common.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.InvalidJsonException;
|
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.AccountingRuleType;
|
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|||||||
-2
@@ -27,6 +27,4 @@ public interface LoanDropdownReadPlatformService {
|
|||||||
|
|
||||||
Collection<TransactionProcessingStrategyData> retreiveTransactionProcessingStrategies();
|
Collection<TransactionProcessingStrategyData> retreiveTransactionProcessingStrategies();
|
||||||
|
|
||||||
List<EnumOptionData> retrieveAccountingRuleTypeOptions();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
-9
@@ -5,7 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.loanproduct.service;
|
package org.mifosplatform.portfolio.loanproduct.service;
|
||||||
|
|
||||||
import static org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations.accountingRuleType;
|
|
||||||
import static org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations.amortizationType;
|
import static org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations.amortizationType;
|
||||||
import static org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations.interestCalculationPeriodType;
|
import static org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations.interestCalculationPeriodType;
|
||||||
import static org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations.interestRateFrequencyType;
|
import static org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations.interestRateFrequencyType;
|
||||||
@@ -21,7 +20,6 @@ import java.util.List;
|
|||||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionProcessingStrategyRepository;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionProcessingStrategyRepository;
|
||||||
import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData;
|
import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.AccountingRuleType;
|
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
||||||
@@ -103,11 +101,4 @@ public class LoanDropdownReadPlatformServiceImpl implements LoanDropdownReadPlat
|
|||||||
return strategyOptions;
|
return strategyOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<EnumOptionData> retrieveAccountingRuleTypeOptions() {
|
|
||||||
List<EnumOptionData> accountingRuleTypeOptions = Arrays.asList(accountingRuleType(AccountingRuleType.NONE),
|
|
||||||
accountingRuleType(AccountingRuleType.CASH_BASED), accountingRuleType(AccountingRuleType.ACCRUAL_BASED));
|
|
||||||
return accountingRuleTypeOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
-12
@@ -11,7 +11,6 @@ import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData;
|
|||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanStatus;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanStatus;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanType;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanType;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.AccountingRuleType;
|
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
||||||
@@ -45,8 +44,6 @@ public class LoanEnumerations {
|
|||||||
return interestType(id);
|
return interestType(id);
|
||||||
} else if (typeName.equals(INTEREST_CALCULATION_PERIOD_TYPE)) {
|
} else if (typeName.equals(INTEREST_CALCULATION_PERIOD_TYPE)) {
|
||||||
return interestCalculationPeriodType(id);
|
return interestCalculationPeriodType(id);
|
||||||
} else if (typeName.equals(ACCOUNTING_RULE_TYPE)) {
|
|
||||||
return accountingRuleType(id);
|
|
||||||
} else if (typeName.equals(LOAN_TYPE)) { return loanType(id); }
|
} else if (typeName.equals(LOAN_TYPE)) { return loanType(id); }
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -337,15 +334,6 @@ public class LoanEnumerations {
|
|||||||
return optionData;
|
return optionData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EnumOptionData accountingRuleType(final int id) {
|
|
||||||
return accountingRuleType(AccountingRuleType.fromInt(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EnumOptionData accountingRuleType(final AccountingRuleType type) {
|
|
||||||
EnumOptionData optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), type.toString());
|
|
||||||
return optionData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EnumOptionData loanType(final Integer loanTypeId) {
|
public static EnumOptionData loanType(final Integer loanTypeId) {
|
||||||
return loanType(LoanType.fromInt(loanTypeId));
|
return loanType(LoanType.fromInt(loanTypeId));
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -10,6 +10,7 @@ import java.sql.ResultSet;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.common.AccountingEnumerations;
|
||||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||||
@@ -140,7 +141,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
final Integer repaymentEvery = JdbcSupport.getInteger(rs, "repaidEvery");
|
final Integer repaymentEvery = JdbcSupport.getInteger(rs, "repaidEvery");
|
||||||
|
|
||||||
final Integer accountingRuleId = JdbcSupport.getInteger(rs, "accountingType");
|
final Integer accountingRuleId = JdbcSupport.getInteger(rs, "accountingType");
|
||||||
final EnumOptionData accountingRuleType = LoanEnumerations.accountingRuleType(accountingRuleId);
|
final EnumOptionData accountingRuleType = AccountingEnumerations.accountingRuleType(accountingRuleId);
|
||||||
|
|
||||||
final BigDecimal interestRatePerPeriod = rs.getBigDecimal("interestRatePerPeriod");
|
final BigDecimal interestRatePerPeriod = rs.getBigDecimal("interestRatePerPeriod");
|
||||||
final BigDecimal minInterestRatePerPeriod = rs.getBigDecimal("minInterestRatePerPeriod");
|
final BigDecimal minInterestRatePerPeriod = rs.getBigDecimal("minInterestRatePerPeriod");
|
||||||
|
|||||||
+13
-3
@@ -5,6 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.savings.api;
|
package org.mifosplatform.portfolio.savings.api;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
@@ -20,12 +22,15 @@ import org.apache.commons.lang.StringUtils;
|
|||||||
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.commands.service.PortfolioCommandSourceWritePlatformService;
|
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||||
|
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
||||||
|
import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService;
|
||||||
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;
|
||||||
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
|
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
|
||||||
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.mifosplatform.portfolio.paymentdetail.PaymentDetailConstants;
|
||||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
|
||||||
import org.mifosplatform.portfolio.savings.service.SavingsAccountReadPlatformService;
|
import org.mifosplatform.portfolio.savings.service.SavingsAccountReadPlatformService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -42,18 +47,21 @@ public class SavingsAccountTransactionsApiResource {
|
|||||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||||
private final SavingsAccountReadPlatformService savingsAccountReadPlatformService;
|
private final SavingsAccountReadPlatformService savingsAccountReadPlatformService;
|
||||||
|
private final CodeValueReadPlatformService codeValueReadPlatformService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public SavingsAccountTransactionsApiResource(final PlatformSecurityContext context,
|
public SavingsAccountTransactionsApiResource(final PlatformSecurityContext context,
|
||||||
final DefaultToApiJsonSerializer<SavingsAccountTransactionData> toApiJsonSerializer,
|
final DefaultToApiJsonSerializer<SavingsAccountTransactionData> toApiJsonSerializer,
|
||||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||||
final SavingsAccountReadPlatformService savingsAccountReadPlatformService) {
|
final SavingsAccountReadPlatformService savingsAccountReadPlatformService,
|
||||||
|
final CodeValueReadPlatformService codeValueReadPlatformService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||||
this.savingsAccountReadPlatformService = savingsAccountReadPlatformService;
|
this.savingsAccountReadPlatformService = savingsAccountReadPlatformService;
|
||||||
|
this.codeValueReadPlatformService = codeValueReadPlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean is(final String commandParam, final String commandValue) {
|
private boolean is(final String commandParam, final String commandValue) {
|
||||||
@@ -71,8 +79,10 @@ public class SavingsAccountTransactionsApiResource {
|
|||||||
|
|
||||||
// FIXME - KW - for now just send back generic default information for
|
// FIXME - KW - for now just send back generic default information for
|
||||||
// both deposit/withdrawal templates
|
// both deposit/withdrawal templates
|
||||||
final SavingsAccountTransactionData savingsAccount = this.savingsAccountReadPlatformService
|
SavingsAccountTransactionData savingsAccount = this.savingsAccountReadPlatformService.retrieveDepositTransactionTemplate(savingsId);
|
||||||
.retrieveDepositTransactionTemplate(savingsId);
|
final Collection<CodeValueData> paymentTypeOptions = codeValueReadPlatformService
|
||||||
|
.retrieveCodeValuesByCode(PaymentDetailConstants.paymentTypeCodeName);
|
||||||
|
savingsAccount = SavingsAccountTransactionData.templateOnTop(savingsAccount, paymentTypeOptions);
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
return this.toApiJsonSerializer.serialize(settings, savingsAccount,
|
return this.toApiJsonSerializer.serialize(settings, savingsAccount,
|
||||||
|
|||||||
+15
-2
@@ -9,6 +9,7 @@ import java.util.Arrays;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.SAVINGS_PRODUCT_ACCOUNTING_PARAMS;
|
||||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountData;
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountData;
|
||||||
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||||
|
|
||||||
@@ -49,6 +50,13 @@ public class SavingsApiConstants {
|
|||||||
public static final String withdrawalFeeTypeParamName = "withdrawalFeeType";
|
public static final String withdrawalFeeTypeParamName = "withdrawalFeeType";
|
||||||
public static final String annualFeeAmountParamName = "annualFeeAmount";
|
public static final String annualFeeAmountParamName = "annualFeeAmount";
|
||||||
public static final String annualFeeOnMonthDayParamName = "annualFeeOnMonthDay";
|
public static final String annualFeeOnMonthDayParamName = "annualFeeOnMonthDay";
|
||||||
|
public static final String accountingRuleParamName = "accountingRule";
|
||||||
|
public static final String paymentTypeIdParamName = "paymentTypeId";
|
||||||
|
public static final String accountNumberParamName = "accountNumber";
|
||||||
|
public static final String checkNumberParamName = "checkNumber";
|
||||||
|
public static final String routingCodeParamName = "routingCode";
|
||||||
|
public static final String receiptNumberParamName = "receiptNumber";
|
||||||
|
public static final String bankNumberParamName = "bankNumber";
|
||||||
|
|
||||||
// transaction parameters
|
// transaction parameters
|
||||||
public static final String transactionDateParamName = "transactionDate";
|
public static final String transactionDateParamName = "transactionDate";
|
||||||
@@ -59,7 +67,11 @@ public class SavingsApiConstants {
|
|||||||
nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName,
|
nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName,
|
||||||
interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName,
|
interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName,
|
||||||
lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName, withdrawalFeeAmountParamName, withdrawalFeeTypeParamName,
|
lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName, withdrawalFeeAmountParamName, withdrawalFeeTypeParamName,
|
||||||
annualFeeAmountParamName, annualFeeOnMonthDayParamName));
|
annualFeeAmountParamName, annualFeeOnMonthDayParamName, accountingRuleParamName,
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(),
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue()));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These parameters will match the class level parameters of
|
* These parameters will match the class level parameters of
|
||||||
@@ -99,7 +111,8 @@ public class SavingsApiConstants {
|
|||||||
"withdrawalFeeTypeOptions"));
|
"withdrawalFeeTypeOptions"));
|
||||||
|
|
||||||
public static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
|
public static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
|
||||||
localeParamName, dateFormatParamName, transactionDateParamName, transactionAmountParamName));
|
localeParamName, dateFormatParamName, transactionDateParamName, transactionAmountParamName, paymentTypeIdParamName,
|
||||||
|
accountNumberParamName, checkNumberParamName, routingCodeParamName, receiptNumberParamName, bankNumberParamName));
|
||||||
|
|
||||||
public static final Set<String> SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName,
|
public static final Set<String> SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName,
|
||||||
"accountId", accountNoParamName, "currency", "amount"));
|
"accountId", accountNoParamName, "currency", "amount"));
|
||||||
|
|||||||
+55
-12
@@ -7,6 +7,9 @@ package org.mifosplatform.portfolio.savings.api;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
@@ -20,9 +23,17 @@ 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.accounting.common.AccountingDropdownReadPlatformService;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingEnumerations;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingRuleType;
|
||||||
|
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.service.ProductToGLAccountMappingReadPlatformService;
|
||||||
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.commands.service.PortfolioCommandSourceWritePlatformService;
|
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||||
|
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
||||||
|
import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService;
|
||||||
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;
|
||||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
@@ -31,6 +42,7 @@ import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSeria
|
|||||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||||
import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService;
|
import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService;
|
||||||
|
import org.mifosplatform.portfolio.paymentdetail.PaymentDetailConstants;
|
||||||
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||||
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
|
import org.mifosplatform.portfolio.savings.domain.SavingsCompoundingInterestPeriodType;
|
||||||
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
|
import org.mifosplatform.portfolio.savings.domain.SavingsInterestCalculationDaysInYearType;
|
||||||
@@ -55,6 +67,9 @@ public class SavingsProductsApiResource {
|
|||||||
private final DefaultToApiJsonSerializer<SavingsProductData> toApiJsonSerializer;
|
private final DefaultToApiJsonSerializer<SavingsProductData> toApiJsonSerializer;
|
||||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||||
|
private final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService;
|
||||||
|
private final CodeValueReadPlatformService codeValueReadPlatformService;
|
||||||
|
private final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public SavingsProductsApiResource(final SavingsProductReadPlatformService savingProductReadPlatformService,
|
public SavingsProductsApiResource(final SavingsProductReadPlatformService savingProductReadPlatformService,
|
||||||
@@ -62,7 +77,9 @@ public class SavingsProductsApiResource {
|
|||||||
final CurrencyReadPlatformService currencyReadPlatformService, final PlatformSecurityContext context,
|
final CurrencyReadPlatformService currencyReadPlatformService, final PlatformSecurityContext context,
|
||||||
final DefaultToApiJsonSerializer<SavingsProductData> toApiJsonSerializer,
|
final DefaultToApiJsonSerializer<SavingsProductData> toApiJsonSerializer,
|
||||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||||
final ApiRequestParameterHelper apiRequestParameterHelper) {
|
final ApiRequestParameterHelper apiRequestParameterHelper, final CodeValueReadPlatformService codeValueReadPlatformService,
|
||||||
|
final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService,
|
||||||
|
final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService) {
|
||||||
this.savingProductReadPlatformService = savingProductReadPlatformService;
|
this.savingProductReadPlatformService = savingProductReadPlatformService;
|
||||||
this.dropdownReadPlatformService = dropdownReadPlatformService;
|
this.dropdownReadPlatformService = dropdownReadPlatformService;
|
||||||
this.currencyReadPlatformService = currencyReadPlatformService;
|
this.currencyReadPlatformService = currencyReadPlatformService;
|
||||||
@@ -70,6 +87,9 @@ public class SavingsProductsApiResource {
|
|||||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||||
|
this.codeValueReadPlatformService = codeValueReadPlatformService;
|
||||||
|
this.accountingDropdownReadPlatformService = accountingDropdownReadPlatformService;
|
||||||
|
this.accountMappingReadPlatformService = accountMappingReadPlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@@ -120,15 +140,25 @@ public class SavingsProductsApiResource {
|
|||||||
|
|
||||||
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_PRODUCT_RESOURCE_NAME);
|
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_PRODUCT_RESOURCE_NAME);
|
||||||
|
|
||||||
SavingsProductData savingProduct = this.savingProductReadPlatformService.retrieveOne(productId);
|
SavingsProductData savingProductData = this.savingProductReadPlatformService.retrieveOne(productId);
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
|
|
||||||
if (settings.isTemplate()) {
|
Map<String, Object> accountingMappings = null;
|
||||||
savingProduct = handleTemplateRelatedData(savingProduct);
|
Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
|
||||||
|
if (savingProductData.hasAccountingEnabled()) {
|
||||||
|
accountingMappings = accountMappingReadPlatformService.fetchAccountMappingDetailsForSavingsProduct(productId,
|
||||||
|
savingProductData.accountingRuleTypeId());
|
||||||
|
paymentChannelToFundSourceMappings = accountMappingReadPlatformService
|
||||||
|
.fetchPaymentTypeToFundSourceMappingsForSavingsProduct(productId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.toApiJsonSerializer.serialize(settings, savingProduct, SavingsApiConstants.SAVINGS_PRODUCT_RESPONSE_DATA_PARAMETERS);
|
if (settings.isTemplate()) {
|
||||||
|
savingProductData = handleTemplateRelatedData(savingProductData, accountingMappings, paymentChannelToFundSourceMappings);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.toApiJsonSerializer
|
||||||
|
.serialize(settings, savingProductData, SavingsApiConstants.SAVINGS_PRODUCT_RESPONSE_DATA_PARAMETERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -139,13 +169,14 @@ public class SavingsProductsApiResource {
|
|||||||
|
|
||||||
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_PRODUCT_RESOURCE_NAME);
|
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_PRODUCT_RESOURCE_NAME);
|
||||||
|
|
||||||
SavingsProductData savingProduct = handleTemplateRelatedData(null);
|
SavingsProductData savingProduct = handleTemplateRelatedData(null, new HashMap<String, Object>(), null);
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
return this.toApiJsonSerializer.serialize(settings, savingProduct, SavingsApiConstants.SAVINGS_PRODUCT_RESPONSE_DATA_PARAMETERS);
|
return this.toApiJsonSerializer.serialize(settings, savingProduct, SavingsApiConstants.SAVINGS_PRODUCT_RESPONSE_DATA_PARAMETERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SavingsProductData handleTemplateRelatedData(final SavingsProductData savingsProduct) {
|
private SavingsProductData handleTemplateRelatedData(final SavingsProductData savingsProduct,
|
||||||
|
final Map<String, Object> accountingMappings, final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings) {
|
||||||
|
|
||||||
final EnumOptionData interestCompoundingPeriodType = SavingsEnumerations
|
final EnumOptionData interestCompoundingPeriodType = SavingsEnumerations
|
||||||
.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.DAILY);
|
.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.DAILY);
|
||||||
@@ -159,6 +190,8 @@ public class SavingsProductsApiResource {
|
|||||||
final EnumOptionData interestCalculationDaysInYearType = SavingsEnumerations
|
final EnumOptionData interestCalculationDaysInYearType = SavingsEnumerations
|
||||||
.interestCalculationDaysInYearType(SavingsInterestCalculationDaysInYearType.DAYS_365);
|
.interestCalculationDaysInYearType(SavingsInterestCalculationDaysInYearType.DAYS_365);
|
||||||
|
|
||||||
|
final EnumOptionData accountingRule = AccountingEnumerations.accountingRuleType(AccountingRuleType.NONE);
|
||||||
|
|
||||||
CurrencyData currency = CurrencyData.blank();
|
CurrencyData currency = CurrencyData.blank();
|
||||||
final Collection<CurrencyData> currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies();
|
final Collection<CurrencyData> currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies();
|
||||||
if (currencyOptions.size() == 1) {
|
if (currencyOptions.size() == 1) {
|
||||||
@@ -182,16 +215,26 @@ public class SavingsProductsApiResource {
|
|||||||
|
|
||||||
final Collection<EnumOptionData> withdrawalFeeTypeOptions = this.dropdownReadPlatformService.retrievewithdrawalFeeTypeOptions();
|
final Collection<EnumOptionData> withdrawalFeeTypeOptions = this.dropdownReadPlatformService.retrievewithdrawalFeeTypeOptions();
|
||||||
|
|
||||||
|
final Collection<CodeValueData> paymentTypeOptions = codeValueReadPlatformService
|
||||||
|
.retrieveCodeValuesByCode(PaymentDetailConstants.paymentTypeCodeName);
|
||||||
|
final Collection<EnumOptionData> accountingRuleOptions = this.accountingDropdownReadPlatformService
|
||||||
|
.retrieveAccountingRuleTypeOptions();
|
||||||
|
final Map<String, List<GLAccountData>> accountingMappingOptions = accountingDropdownReadPlatformService
|
||||||
|
.retrieveAccountMappingOptionsForSavingsProducts();
|
||||||
|
|
||||||
SavingsProductData savingsProductToReturn = null;
|
SavingsProductData savingsProductToReturn = null;
|
||||||
if (savingsProduct != null) {
|
if (savingsProduct != null) {
|
||||||
savingsProductToReturn = SavingsProductData.withTemplate(savingsProduct, currencyOptions, interestCompoundingPeriodTypeOptions,
|
savingsProductToReturn = SavingsProductData.withTemplate(savingsProduct, accountingMappings,
|
||||||
|
paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions,
|
||||||
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
||||||
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions);
|
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions,
|
||||||
|
accountingMappingOptions);
|
||||||
} else {
|
} else {
|
||||||
savingsProductToReturn = SavingsProductData.template(currency, interestCompoundingPeriodType, interestPostingPeriodType,
|
savingsProductToReturn = SavingsProductData.template(currency, interestCompoundingPeriodType, interestPostingPeriodType,
|
||||||
interestCalculationType, interestCalculationDaysInYearType, currencyOptions, interestCompoundingPeriodTypeOptions,
|
interestCalculationType, interestCalculationDaysInYearType, accountingRule, currencyOptions,
|
||||||
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
|
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
|
||||||
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions);
|
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions,
|
||||||
|
paymentTypeOptions, accountingRuleOptions, accountingMappingOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
return savingsProductToReturn;
|
return savingsProductToReturn;
|
||||||
|
|||||||
+29
-5
@@ -6,9 +6,12 @@
|
|||||||
package org.mifosplatform.portfolio.savings.data;
|
package org.mifosplatform.portfolio.savings.data;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
|
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
||||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||||
|
import org.mifosplatform.portfolio.paymentdetail.data.PaymentDetailData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immutable data object representing a savings account transaction.
|
* Immutable data object representing a savings account transaction.
|
||||||
@@ -22,11 +25,18 @@ public class SavingsAccountTransactionData {
|
|||||||
private final String accountNo;
|
private final String accountNo;
|
||||||
private final LocalDate date;
|
private final LocalDate date;
|
||||||
private final CurrencyData currency;
|
private final CurrencyData currency;
|
||||||
|
private final PaymentDetailData paymentDetailData;
|
||||||
private final BigDecimal amount;
|
private final BigDecimal amount;
|
||||||
|
|
||||||
|
// templates
|
||||||
|
final Collection<CodeValueData> paymentTypeOptions;
|
||||||
|
|
||||||
public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
||||||
final Long savingsId, final String savingsAccountNo, final LocalDate date, final CurrencyData currency, final BigDecimal amount) {
|
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
|
||||||
return new SavingsAccountTransactionData(id, transactionType, savingsId, savingsAccountNo, date, currency, amount);
|
final CurrencyData currency, final BigDecimal amount) {
|
||||||
|
final Collection<CodeValueData> paymentTypeOptions = null;
|
||||||
|
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency,
|
||||||
|
amount, paymentTypeOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SavingsAccountTransactionData template(final Long savingsId, final String savingsAccountNo,
|
public static SavingsAccountTransactionData template(final Long savingsId, final String savingsAccountNo,
|
||||||
@@ -34,17 +44,31 @@ public class SavingsAccountTransactionData {
|
|||||||
final Long id = null;
|
final Long id = null;
|
||||||
final SavingsAccountTransactionEnumData transactionType = null;
|
final SavingsAccountTransactionEnumData transactionType = null;
|
||||||
final BigDecimal amount = null;
|
final BigDecimal amount = null;
|
||||||
return new SavingsAccountTransactionData(id, transactionType, savingsId, savingsAccountNo, defaultLocalDate, currency, amount);
|
final PaymentDetailData paymentDetailData = null;
|
||||||
|
final Collection<CodeValueData> paymentTypeOptions = null;
|
||||||
|
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, defaultLocalDate,
|
||||||
|
currency, amount, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType, final Long savingsId,
|
public static SavingsAccountTransactionData templateOnTop(final SavingsAccountTransactionData savingsAccountTransactionData,
|
||||||
final String savingsAccountNo, final LocalDate date, final CurrencyData currency, final BigDecimal amount) {
|
final Collection<CodeValueData> paymentTypeOptions) {
|
||||||
|
return new SavingsAccountTransactionData(savingsAccountTransactionData.id, savingsAccountTransactionData.transactionType,
|
||||||
|
savingsAccountTransactionData.paymentDetailData, savingsAccountTransactionData.accountId,
|
||||||
|
savingsAccountTransactionData.accountNo, savingsAccountTransactionData.date, savingsAccountTransactionData.currency,
|
||||||
|
savingsAccountTransactionData.amount, paymentTypeOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
||||||
|
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
|
||||||
|
final CurrencyData currency, final BigDecimal amount, final Collection<CodeValueData> paymentTypeOptions) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.transactionType = transactionType;
|
this.transactionType = transactionType;
|
||||||
|
this.paymentDetailData = paymentDetailData;
|
||||||
this.accountId = savingsId;
|
this.accountId = savingsId;
|
||||||
this.accountNo = savingsAccountNo;
|
this.accountNo = savingsAccountNo;
|
||||||
this.date = date;
|
this.date = date;
|
||||||
this.currency = currency;
|
this.currency = currency;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
|
this.paymentTypeOptions = paymentTypeOptions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+20
@@ -5,15 +5,24 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.savings.data;
|
package org.mifosplatform.portfolio.savings.data;
|
||||||
|
|
||||||
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.accountNumberParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.activationDateParamName;
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.activationDateParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.bankNumberParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.checkNumberParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.paymentTypeIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.receiptNumberParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.routingCodeParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.transactionAmountParamName;
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.transactionAmountParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.transactionDateParamName;
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.transactionDateParamName;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
@@ -62,6 +71,17 @@ public class SavingsAccountTransactionDataValidator {
|
|||||||
final BigDecimal transactionAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(transactionAmountParamName, element);
|
final BigDecimal transactionAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(transactionAmountParamName, element);
|
||||||
baseDataValidator.reset().parameter(transactionAmountParamName).value(transactionAmount).notNull().positiveAmount();
|
baseDataValidator.reset().parameter(transactionAmountParamName).value(transactionAmount).notNull().positiveAmount();
|
||||||
|
|
||||||
|
// Validate all string payment detail fields for max length
|
||||||
|
final Integer paymentTypeId = fromApiJsonHelper.extractIntegerWithLocaleNamed(paymentTypeIdParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(paymentTypeIdParamName).value(paymentTypeId).ignoreIfNull().integerGreaterThanZero();
|
||||||
|
final Set<String> paymentDetailParameters = new HashSet<String>(Arrays.asList(accountNumberParamName, checkNumberParamName,
|
||||||
|
routingCodeParamName, receiptNumberParamName, bankNumberParamName));
|
||||||
|
for (String paymentDetailParameterName : paymentDetailParameters) {
|
||||||
|
final String paymentDetailParameterValue = fromApiJsonHelper.extractStringNamed(paymentDetailParameterName, element);
|
||||||
|
baseDataValidator.reset().parameter(paymentDetailParameterName).value(paymentDetailParameterValue).ignoreIfNull()
|
||||||
|
.notExceedingLengthOf(50);
|
||||||
|
}
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+33
@@ -5,6 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.savings.data;
|
package org.mifosplatform.portfolio.savings.data;
|
||||||
|
|
||||||
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransactionType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immutable data object represent savings account transaction type
|
* Immutable data object represent savings account transaction type
|
||||||
* enumerations.
|
* enumerations.
|
||||||
@@ -16,9 +18,40 @@ public class SavingsAccountTransactionEnumData {
|
|||||||
private final String code;
|
private final String code;
|
||||||
private final String value;
|
private final String value;
|
||||||
|
|
||||||
|
private final boolean deposit;
|
||||||
|
private final boolean withdrawal;
|
||||||
|
private final boolean interestPosting;
|
||||||
|
private final boolean feeDeduction;
|
||||||
|
|
||||||
public SavingsAccountTransactionEnumData(final Long id, final String code, final String value) {
|
public SavingsAccountTransactionEnumData(final Long id, final String code, final String value) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
this.deposit = Long.valueOf(SavingsAccountTransactionType.DEPOSIT.getValue()).equals(this.id);
|
||||||
|
this.withdrawal = Long.valueOf(SavingsAccountTransactionType.WITHDRAWAL.getValue()).equals(this.id);
|
||||||
|
this.interestPosting = Long.valueOf(SavingsAccountTransactionType.INTEREST_POSTING.getValue()).equals(this.id);
|
||||||
|
this.feeDeduction = Long.valueOf(SavingsAccountTransactionType.ANNUAL_FEE.getValue()).equals(this.id)
|
||||||
|
|| Long.valueOf(SavingsAccountTransactionType.WITHDRAWAL_FEE.getValue()).equals(this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDeposit() {
|
||||||
|
return this.deposit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWithdrawal() {
|
||||||
|
return this.withdrawal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDepositOrWithdrawal() {
|
||||||
|
return this.deposit || this.withdrawal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInterestPosting() {
|
||||||
|
return this.interestPosting;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFeeDeduction() {
|
||||||
|
return this.feeDeduction;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+90
-23
@@ -7,8 +7,14 @@ package org.mifosplatform.portfolio.savings.data;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.joda.time.MonthDay;
|
import org.joda.time.MonthDay;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingRuleType;
|
||||||
|
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
|
||||||
|
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
||||||
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;
|
||||||
|
|
||||||
@@ -34,6 +40,13 @@ public class SavingsProductData {
|
|||||||
private final BigDecimal annualFeeAmount;
|
private final BigDecimal annualFeeAmount;
|
||||||
private final MonthDay annualFeeOnMonthDay;
|
private final MonthDay annualFeeOnMonthDay;
|
||||||
|
|
||||||
|
// accounting
|
||||||
|
private final EnumOptionData accountingRule;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Map<String, Object> accountingMappings;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings;
|
||||||
|
|
||||||
// template
|
// template
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private final Collection<CurrencyData> currencyOptions;
|
private final Collection<CurrencyData> currencyOptions;
|
||||||
@@ -49,15 +62,23 @@ public class SavingsProductData {
|
|||||||
private final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
|
private final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private final Collection<EnumOptionData> withdrawalFeeTypeOptions;
|
private final Collection<EnumOptionData> withdrawalFeeTypeOptions;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Collection<CodeValueData> paymentTypeOptions;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Collection<EnumOptionData> accountingRuleOptions;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Map<String, List<GLAccountData>> accountingMappingOptions;
|
||||||
|
|
||||||
public static SavingsProductData template(final CurrencyData currency, final EnumOptionData interestCompoundingPeriodType,
|
public static SavingsProductData template(final CurrencyData currency, final EnumOptionData interestCompoundingPeriodType,
|
||||||
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
|
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
|
||||||
final EnumOptionData interestCalculationDaysInYearType, final Collection<CurrencyData> currencyOptions,
|
final EnumOptionData interestCalculationDaysInYearType, final EnumOptionData accountingRule,
|
||||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
|
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
|
||||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
|
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
|
||||||
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
||||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions) {
|
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
|
||||||
|
final Collection<CodeValueData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
|
||||||
|
final Map<String, List<GLAccountData>> accountingMappingOptions) {
|
||||||
|
|
||||||
final Long id = null;
|
final Long id = null;
|
||||||
final String name = null;
|
final String name = null;
|
||||||
@@ -70,34 +91,42 @@ public class SavingsProductData {
|
|||||||
final EnumOptionData withdrawalFeeType = null;
|
final EnumOptionData withdrawalFeeType = null;
|
||||||
final BigDecimal annualFeeAmount = null;
|
final BigDecimal annualFeeAmount = null;
|
||||||
final MonthDay annualFeeMonthDay = null;
|
final MonthDay annualFeeMonthDay = null;
|
||||||
|
final Map<String, Object> accountingMappings = null;
|
||||||
|
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
|
||||||
|
|
||||||
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
||||||
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||||
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType, annualFeeAmount,
|
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType, accountingRule, annualFeeAmount,
|
||||||
annualFeeMonthDay, currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
|
annualFeeMonthDay, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
|
||||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
|
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
|
||||||
withdrawalFeeTypeOptions);
|
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
|
||||||
|
accountingRuleOptions, accountingMappingOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link SavingsProductData} that contains and exist
|
* Returns a {@link SavingsProductData} that contains and exist
|
||||||
* {@link SavingsProductData} data with further template data for dropdowns.
|
* {@link SavingsProductData} data with further template data for dropdowns.
|
||||||
*/
|
*/
|
||||||
public static SavingsProductData withTemplate(final SavingsProductData existingProduct, final Collection<CurrencyData> currencyOptions,
|
public static SavingsProductData withTemplate(final SavingsProductData existingProduct, final Map<String, Object> accountingMappings,
|
||||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
|
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
|
||||||
|
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
|
||||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
|
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
|
||||||
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
||||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions) {
|
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
|
||||||
|
final Collection<CodeValueData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
|
||||||
|
final Map<String, List<GLAccountData>> accountingMappingOptions) {
|
||||||
|
|
||||||
return new SavingsProductData(existingProduct.id, existingProduct.name, existingProduct.description, existingProduct.currency,
|
return new SavingsProductData(existingProduct.id, existingProduct.name, existingProduct.description, existingProduct.currency,
|
||||||
existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
|
existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
|
||||||
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
|
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
|
||||||
existingProduct.interestCalculationDaysInYearType, existingProduct.minRequiredOpeningBalance,
|
existingProduct.interestCalculationDaysInYearType, existingProduct.minRequiredOpeningBalance,
|
||||||
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType, existingProduct.withdrawalFeeAmount,
|
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType, existingProduct.withdrawalFeeAmount,
|
||||||
existingProduct.withdrawalFeeType, existingProduct.annualFeeAmount, existingProduct.annualFeeOnMonthDay, currencyOptions,
|
existingProduct.withdrawalFeeType, existingProduct.accountingRule, existingProduct.annualFeeAmount,
|
||||||
|
existingProduct.annualFeeOnMonthDay, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
|
||||||
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
|
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
|
||||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions);
|
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
|
||||||
|
accountingRuleOptions, accountingMappingOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SavingsProductData instance(final Long id, final String name, final String description, final CurrencyData currency,
|
public static SavingsProductData instance(final Long id, final String name, final String description, final CurrencyData currency,
|
||||||
@@ -105,7 +134,11 @@ public class SavingsProductData {
|
|||||||
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
|
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
|
||||||
final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||||
final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType, final BigDecimal withdrawalFeeAmount,
|
final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType, final BigDecimal withdrawalFeeAmount,
|
||||||
final EnumOptionData withdrawalFeeType, final BigDecimal annualFeeAmount, final MonthDay annualFeeOnMonthDay) {
|
final EnumOptionData withdrawalFeeType, final BigDecimal annualFeeAmount, final MonthDay annualFeeOnMonthDay,
|
||||||
|
final EnumOptionData accountingType) {
|
||||||
|
|
||||||
|
final Map<String, Object> accountingMappings = null;
|
||||||
|
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
|
||||||
|
|
||||||
final Collection<CurrencyData> currencyOptions = null;
|
final Collection<CurrencyData> currencyOptions = null;
|
||||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
||||||
@@ -114,13 +147,17 @@ public class SavingsProductData {
|
|||||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||||
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
|
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
|
||||||
|
final Collection<CodeValueData> paymentTypeOptions = null;
|
||||||
|
final Collection<EnumOptionData> accountingRuleOptions = null;
|
||||||
|
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
|
||||||
|
|
||||||
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
||||||
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||||
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType, annualFeeAmount,
|
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType, accountingType, annualFeeAmount,
|
||||||
annualFeeOnMonthDay, currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
|
annualFeeOnMonthDay, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
|
||||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
|
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
|
||||||
withdrawalFeeTypeOptions);
|
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
|
||||||
|
accountingRuleOptions, accountingMappingOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SavingsProductData lookup(final Long id, final String name) {
|
public static SavingsProductData lookup(final Long id, final String name) {
|
||||||
@@ -137,8 +174,11 @@ public class SavingsProductData {
|
|||||||
final EnumOptionData lockinPeriodFrequencyType = null;
|
final EnumOptionData lockinPeriodFrequencyType = null;
|
||||||
final BigDecimal withdrawalFeeAmount = null;
|
final BigDecimal withdrawalFeeAmount = null;
|
||||||
final EnumOptionData withdrawalFeeType = null;
|
final EnumOptionData withdrawalFeeType = null;
|
||||||
|
final EnumOptionData accountingType = null;
|
||||||
final BigDecimal annualFeeAmount = null;
|
final BigDecimal annualFeeAmount = null;
|
||||||
final MonthDay annualFeeMonthDay = null;
|
final MonthDay annualFeeMonthDay = null;
|
||||||
|
final Map<String, Object> accountingMappings = null;
|
||||||
|
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
|
||||||
|
|
||||||
final Collection<CurrencyData> currencyOptions = null;
|
final Collection<CurrencyData> currencyOptions = null;
|
||||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
|
||||||
@@ -147,13 +187,17 @@ public class SavingsProductData {
|
|||||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
|
||||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||||
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
|
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
|
||||||
|
final Collection<CodeValueData> paymentTypeOptions = null;
|
||||||
|
final Collection<EnumOptionData> accountingRuleOptions = null;
|
||||||
|
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
|
||||||
|
|
||||||
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
return new SavingsProductData(id, name, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
||||||
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||||
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType, annualFeeAmount,
|
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType, accountingType, annualFeeAmount,
|
||||||
annualFeeMonthDay, currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
|
annualFeeMonthDay, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
|
||||||
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
|
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
|
||||||
withdrawalFeeTypeOptions);
|
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
|
||||||
|
accountingRuleOptions, accountingMappingOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SavingsProductData(final Long id, final String name, final String description, final CurrencyData currency,
|
private SavingsProductData(final Long id, final String name, final String description, final CurrencyData currency,
|
||||||
@@ -161,12 +205,16 @@ public class SavingsProductData {
|
|||||||
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
|
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
|
||||||
final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||||
final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType, final BigDecimal withdrawalFeeAmount,
|
final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType, final BigDecimal withdrawalFeeAmount,
|
||||||
final EnumOptionData withdrawalFeeType, final BigDecimal annualFeeAmount, final MonthDay annualFeeOnMonthDay,
|
final EnumOptionData withdrawalFeeType, final EnumOptionData accountingType, final BigDecimal annualFeeAmount,
|
||||||
|
final MonthDay annualFeeOnMonthDay, final Map<String, Object> accountingMappings,
|
||||||
|
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
|
||||||
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
|
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
|
||||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
|
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
|
||||||
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
final Collection<EnumOptionData> interestCalculationTypeOptions,
|
||||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
|
||||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions) {
|
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
|
||||||
|
final Collection<CodeValueData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
|
||||||
|
final Map<String, List<GLAccountData>> accountingMappingOptions) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
@@ -176,6 +224,7 @@ public class SavingsProductData {
|
|||||||
this.interestPostingPeriodType = interestPostingPeriodType;
|
this.interestPostingPeriodType = interestPostingPeriodType;
|
||||||
this.interestCalculationType = interestCalculationType;
|
this.interestCalculationType = interestCalculationType;
|
||||||
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType;
|
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType;
|
||||||
|
this.accountingRule = accountingType;
|
||||||
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
|
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
|
||||||
this.lockinPeriodFrequency = lockinPeriodFrequency;
|
this.lockinPeriodFrequency = lockinPeriodFrequency;
|
||||||
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType;
|
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType;
|
||||||
@@ -191,5 +240,23 @@ public class SavingsProductData {
|
|||||||
this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions;
|
this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions;
|
||||||
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
|
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
|
||||||
this.withdrawalFeeTypeOptions = withdrawalFeeTypeOptions;
|
this.withdrawalFeeTypeOptions = withdrawalFeeTypeOptions;
|
||||||
|
|
||||||
|
this.paymentTypeOptions = paymentTypeOptions;
|
||||||
|
this.accountingMappingOptions = accountingMappingOptions;
|
||||||
|
this.accountingRuleOptions = accountingRuleOptions;
|
||||||
|
if (accountingMappings == null || accountingMappings.isEmpty()) {
|
||||||
|
this.accountingMappings = null;
|
||||||
|
} else {
|
||||||
|
this.accountingMappings = accountingMappings;
|
||||||
|
}
|
||||||
|
this.paymentChannelToFundSourceMappings = paymentChannelToFundSourceMappings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasAccountingEnabled() {
|
||||||
|
return this.accountingRule.getId() > AccountingRuleType.NONE.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int accountingRuleTypeId() {
|
||||||
|
return this.accountingRule.getId().intValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+95
@@ -28,10 +28,13 @@ import java.lang.reflect.Type;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.joda.time.MonthDay;
|
import org.joda.time.MonthDay;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingConstants.SAVINGS_PRODUCT_ACCOUNTING_PARAMS;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingRuleType;
|
||||||
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.InvalidJsonException;
|
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||||
@@ -40,7 +43,9 @@ import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@@ -154,6 +159,35 @@ public class SavingsProductDataValidator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// accounting related data validation
|
||||||
|
final Integer accountingRuleType = fromApiJsonHelper.extractIntegerNamed("accountingRule", element, Locale.getDefault());
|
||||||
|
baseDataValidator.reset().parameter("accountingRule").value(accountingRuleType).notNull().inMinMaxRange(1, 3);
|
||||||
|
|
||||||
|
if (isCashBasedAccounting(accountingRuleType)) {
|
||||||
|
|
||||||
|
final Long savingsControlAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue())
|
||||||
|
.value(savingsControlAccountId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long savingsReferenceAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(), element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue())
|
||||||
|
.value(savingsReferenceAccountId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long interestOnSavingsAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue())
|
||||||
|
.value(interestOnSavingsAccountId).notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long incomeFromFeeId = fromApiJsonHelper.extractLongNamed(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
|
||||||
|
element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue()).value(incomeFromFeeId)
|
||||||
|
.notNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
validatePaymentChannelFundSourceMappings(baseDataValidator, element);
|
||||||
|
}
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,10 +284,71 @@ public class SavingsProductDataValidator {
|
|||||||
baseDataValidator.reset().parameter(annualFeeOnMonthDayParamName).value(monthDayOfAnnualFee).ignoreIfNull();
|
baseDataValidator.reset().parameter(annualFeeOnMonthDayParamName).value(monthDayOfAnnualFee).ignoreIfNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Long savingsControlAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue(), element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_CONTROL.getValue()).value(savingsControlAccountId)
|
||||||
|
.ignoreIfNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long savingsReferenceAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue(), element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.SAVINGS_REFERENCE.getValue())
|
||||||
|
.value(savingsReferenceAccountId).ignoreIfNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long interestOnSavingsAccountId = fromApiJsonHelper.extractLongNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue(), element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_SAVINGS.getValue())
|
||||||
|
.value(interestOnSavingsAccountId).ignoreIfNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
final Long incomeFromFeeId = fromApiJsonHelper.extractLongNamed(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
|
||||||
|
element);
|
||||||
|
baseDataValidator.reset().parameter(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue()).value(incomeFromFeeId)
|
||||||
|
.ignoreIfNull().integerGreaterThanZero();
|
||||||
|
|
||||||
|
validatePaymentChannelFundSourceMappings(baseDataValidator, element);
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isCashBasedAccounting(final Integer accountingRuleType) {
|
||||||
|
return AccountingRuleType.CASH_BASED.getValue().equals(accountingRuleType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validation for advanced accounting options
|
||||||
|
*
|
||||||
|
* @param baseDataValidator
|
||||||
|
* @param element
|
||||||
|
*/
|
||||||
|
private void validatePaymentChannelFundSourceMappings(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
|
||||||
|
if (fromApiJsonHelper.parameterExists(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element)) {
|
||||||
|
JsonArray paymentChannelMappingArray = fromApiJsonHelper.extractJsonArrayNamed(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element);
|
||||||
|
if (paymentChannelMappingArray != null && paymentChannelMappingArray.size() > 0) {
|
||||||
|
int i = 0;
|
||||||
|
do {
|
||||||
|
final JsonObject jsonObject = paymentChannelMappingArray.get(i).getAsJsonObject();
|
||||||
|
final Long paymentTypeId = jsonObject.get(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_TYPE.getValue()).getAsLong();
|
||||||
|
final Long paymentSpecificFundAccountId = jsonObject.get(SAVINGS_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue())
|
||||||
|
.getAsLong();
|
||||||
|
baseDataValidator
|
||||||
|
.reset()
|
||||||
|
.parameter(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue() + "[" + i + "]."
|
||||||
|
+ SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_TYPE.toString()).value(paymentTypeId).notNull()
|
||||||
|
.integerGreaterThanZero();
|
||||||
|
baseDataValidator
|
||||||
|
.reset()
|
||||||
|
.parameter(
|
||||||
|
SAVINGS_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue() + "[" + i + "]."
|
||||||
|
+ SAVINGS_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue()).value(paymentSpecificFundAccountId)
|
||||||
|
.notNull().integerGreaterThanZero();
|
||||||
|
i++;
|
||||||
|
} while (i < paymentChannelMappingArray.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+94
-7
@@ -16,8 +16,10 @@ import java.math.MathContext;
|
|||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -47,11 +49,13 @@ import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
|||||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||||
import org.mifosplatform.infrastructure.security.service.RandomPasswordGenerator;
|
import org.mifosplatform.infrastructure.security.service.RandomPasswordGenerator;
|
||||||
|
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
import org.mifosplatform.portfolio.client.domain.Client;
|
import org.mifosplatform.portfolio.client.domain.Client;
|
||||||
import org.mifosplatform.portfolio.group.domain.Group;
|
import org.mifosplatform.portfolio.group.domain.Group;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||||
|
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
import org.mifosplatform.portfolio.savings.api.SavingsApiConstants;
|
import org.mifosplatform.portfolio.savings.api.SavingsApiConstants;
|
||||||
import org.mifosplatform.portfolio.savings.exception.InsufficientAccountBalanceException;
|
import org.mifosplatform.portfolio.savings.exception.InsufficientAccountBalanceException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -271,7 +275,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
return SavingsAccountStatusType.fromInt(this.status).isActive();
|
return SavingsAccountStatusType.fromInt(this.status).isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void activate(final DateTimeFormatter formatter, final LocalDate activationDate) {
|
public void activate(final DateTimeFormatter formatter, final LocalDate activationDate, List<Long> existingTransactionIds,
|
||||||
|
List<Long> existingReversedTransactionIds) {
|
||||||
|
|
||||||
if (isActive()) {
|
if (isActive()) {
|
||||||
final String defaultUserMessage = "Cannot activate account. Account is already active.";
|
final String defaultUserMessage = "Cannot activate account. Account is already active.";
|
||||||
@@ -305,7 +310,12 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
// activating account.
|
// activating account.
|
||||||
final Money minRequiredOpeningBalance = Money.of(this.currency, this.minRequiredOpeningBalance);
|
final Money minRequiredOpeningBalance = Money.of(this.currency, this.minRequiredOpeningBalance);
|
||||||
if (minRequiredOpeningBalance.isGreaterThanZero()) {
|
if (minRequiredOpeningBalance.isGreaterThanZero()) {
|
||||||
deposit(formatter, activationDate, minRequiredOpeningBalance.getAmount());
|
/**
|
||||||
|
* Vishwas: TODO activate API should be modified to accept payment
|
||||||
|
* details (for entering minimum balance)
|
||||||
|
**/
|
||||||
|
deposit(formatter, activationDate, minRequiredOpeningBalance.getAmount(), existingTransactionIds,
|
||||||
|
existingReversedTransactionIds, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,7 +343,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
return lockedInUntilLocalDate;
|
return lockedInUntilLocalDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void postInterest(final LocalDate interestPostingUpToDate) {
|
public void postInterest(final LocalDate interestPostingUpToDate, List<Long> existingTransactionIds,
|
||||||
|
List<Long> existingReversedTransactionIds) {
|
||||||
|
|
||||||
final SavingsInterestPostingPeriodType postingPeriodType = SavingsInterestPostingPeriodType.fromInt(this.interestPostingPeriodType);
|
final SavingsInterestPostingPeriodType postingPeriodType = SavingsInterestPostingPeriodType.fromInt(this.interestPostingPeriodType);
|
||||||
final List<LocalDate> postingLocalDates = determineInterestPostingDates(getActivationLocalDate(), interestPostingUpToDate,
|
final List<LocalDate> postingLocalDates = determineInterestPostingDates(getActivationLocalDate(), interestPostingUpToDate,
|
||||||
@@ -344,6 +355,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
Money interestPostedToDate = Money.zero(this.currency);
|
Money interestPostedToDate = Money.zero(this.currency);
|
||||||
|
|
||||||
boolean recalucateDailyBalanceDetails = false;
|
boolean recalucateDailyBalanceDetails = false;
|
||||||
|
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||||
|
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||||
for (LocalDate postingDate : postingLocalDates) {
|
for (LocalDate postingDate : postingLocalDates) {
|
||||||
Money interestEarnedToBePostedForPeriod = findInterestEarnedToBePostedOn(interestPostedToDate, postingDate, compoundingPeriods);
|
Money interestEarnedToBePostedForPeriod = findInterestEarnedToBePostedOn(interestPostedToDate, postingDate, compoundingPeriods);
|
||||||
|
|
||||||
@@ -734,7 +747,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SavingsAccountTransaction deposit(final DateTimeFormatter formatter, final LocalDate transactionDate,
|
public SavingsAccountTransaction deposit(final DateTimeFormatter formatter, final LocalDate transactionDate,
|
||||||
final BigDecimal transactionAmount) {
|
final BigDecimal transactionAmount, List<Long> existingTransactionIds, List<Long> existingReversedTransactionIds,
|
||||||
|
final PaymentDetail paymentDetail) {
|
||||||
|
|
||||||
if (isNotActive()) {
|
if (isNotActive()) {
|
||||||
final String defaultUserMessage = "Transaction is not allowed. Account is not active.";
|
final String defaultUserMessage = "Transaction is not allowed. Account is not active.";
|
||||||
@@ -771,8 +785,11 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||||
|
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||||
|
|
||||||
final Money amount = Money.of(this.currency, transactionAmount);
|
final Money amount = Money.of(this.currency, transactionAmount);
|
||||||
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(this, transactionDate, amount);
|
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(this, paymentDetail, transactionDate, amount);
|
||||||
this.transactions.add(transaction);
|
this.transactions.add(transaction);
|
||||||
|
|
||||||
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
||||||
@@ -792,7 +809,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SavingsAccountTransaction withdraw(final DateTimeFormatter formatter, final LocalDate transactionDate,
|
public SavingsAccountTransaction withdraw(final DateTimeFormatter formatter, final LocalDate transactionDate,
|
||||||
final BigDecimal transactionAmount) {
|
final BigDecimal transactionAmount, List<Long> existingTransactionIds, List<Long> existingReversedTransactionIds,
|
||||||
|
final PaymentDetail paymentDetail) {
|
||||||
|
|
||||||
if (isNotActive()) {
|
if (isNotActive()) {
|
||||||
|
|
||||||
@@ -843,6 +861,9 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||||
|
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||||
|
|
||||||
final Money transactionAmountMoney = Money.of(this.currency, transactionAmount);
|
final Money transactionAmountMoney = Money.of(this.currency, transactionAmount);
|
||||||
|
|
||||||
if (isNotEnoughFundsToWithdraw(transactionAmountMoney)) {
|
if (isNotEnoughFundsToWithdraw(transactionAmountMoney)) {
|
||||||
@@ -850,7 +871,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
throw new InsufficientAccountBalanceException("transactionAmount", getAccountBalance(), transactionAmount);
|
throw new InsufficientAccountBalanceException("transactionAmount", getAccountBalance(), transactionAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
final SavingsAccountTransaction transaction = SavingsAccountTransaction.withdrawal(this, transactionDate, transactionAmountMoney);
|
final SavingsAccountTransaction transaction = SavingsAccountTransaction.withdrawal(this, paymentDetail, transactionDate,
|
||||||
|
transactionAmountMoney);
|
||||||
this.transactions.add(transaction);
|
this.transactions.add(transaction);
|
||||||
|
|
||||||
if (isAutomaticWithdrawalFee()) {
|
if (isAutomaticWithdrawalFee()) {
|
||||||
@@ -875,6 +897,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***TODO Fixme: Annual fee seems to be added for all withdrawals?**/
|
||||||
final Money annualFee = Money.of(this.currency, this.annualFeeAmount);
|
final Money annualFee = Money.of(this.currency, this.annualFeeAmount);
|
||||||
SavingsAccountTransaction annualFeeTransaction = SavingsAccountTransaction.annualFee(this, transactionDate, annualFee);
|
SavingsAccountTransaction annualFeeTransaction = SavingsAccountTransaction.annualFee(this, transactionDate, annualFee);
|
||||||
this.transactions.add(annualFeeTransaction);
|
this.transactions.add(annualFeeTransaction);
|
||||||
@@ -1096,6 +1119,53 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> deriveAccountingBridgeData(final CurrencyData currencyData, final List<Long> existingTransactionIds,
|
||||||
|
final List<Long> existingReversedTransactionIds) {
|
||||||
|
|
||||||
|
final Map<String, Object> accountingBridgeData = new LinkedHashMap<String, Object>();
|
||||||
|
accountingBridgeData.put("savingsId", this.getId());
|
||||||
|
accountingBridgeData.put("savingsProductId", this.productId());
|
||||||
|
accountingBridgeData.put("officeId", this.officeId());
|
||||||
|
accountingBridgeData.put("cashBasedAccountingEnabled", this.isCashBasedAccountingEnabledOnSavingsProduct());
|
||||||
|
accountingBridgeData.put("accrualBasedAccountingEnabled", this.isAccrualBasedAccountingEnabledOnSavingsProduct());
|
||||||
|
|
||||||
|
final List<Map<String, Object>> newLoanTransactions = new ArrayList<Map<String, Object>>();
|
||||||
|
for (SavingsAccountTransaction transaction : this.transactions) {
|
||||||
|
if (transaction.isReversed() && !existingReversedTransactionIds.contains(transaction.getId())) {
|
||||||
|
newLoanTransactions.add(transaction.toMapData(currencyData));
|
||||||
|
} else if (!existingTransactionIds.contains(transaction.getId())) {
|
||||||
|
newLoanTransactions.add(transaction.toMapData(currencyData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
accountingBridgeData.put("newSavingsTransactions", newLoanTransactions);
|
||||||
|
return accountingBridgeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<Long> findExistingTransactionIds() {
|
||||||
|
|
||||||
|
Collection<Long> ids = new ArrayList<Long>();
|
||||||
|
|
||||||
|
for (SavingsAccountTransaction transaction : this.transactions) {
|
||||||
|
ids.add(transaction.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<Long> findExistingReversedTransactionIds() {
|
||||||
|
|
||||||
|
final Collection<Long> ids = new ArrayList<Long>();
|
||||||
|
|
||||||
|
for (SavingsAccountTransaction transaction : this.transactions) {
|
||||||
|
if (transaction.isReversed()) {
|
||||||
|
ids.add(transaction.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
public void update(final Client client) {
|
public void update(final Client client) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
}
|
}
|
||||||
@@ -1117,6 +1187,18 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
return this.accountNumberRequiresAutoGeneration;
|
return this.accountNumberRequiresAutoGeneration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long productId() {
|
||||||
|
return this.product.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean isCashBasedAccountingEnabledOnSavingsProduct() {
|
||||||
|
return this.product.isCashBasedAccountingEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean isAccrualBasedAccountingEnabledOnSavingsProduct() {
|
||||||
|
return this.product.isAccrualBasedAccountingEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
public Long officeId() {
|
public Long officeId() {
|
||||||
Long officeId = null;
|
Long officeId = null;
|
||||||
if (this.client != null) {
|
if (this.client != null) {
|
||||||
@@ -1142,4 +1224,9 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MonetaryCurrency getCurrency() {
|
||||||
|
return this.currency;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-2
@@ -21,6 +21,7 @@ import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.withdr
|
|||||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.withdrawalFeeTypeParamName;
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.withdrawalFeeTypeParamName;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
@@ -64,8 +65,12 @@ public class SavingsAccountAssembler {
|
|||||||
* Assembles a new {@link SavingsAccount} from JSON details passed in
|
* Assembles a new {@link SavingsAccount} from JSON details passed in
|
||||||
* request inheriting details where relevant from chosen
|
* request inheriting details where relevant from chosen
|
||||||
* {@link SavingsProduct}.
|
* {@link SavingsProduct}.
|
||||||
|
*
|
||||||
|
* @param existingReversedTransactionIds
|
||||||
|
* @param existingTransactionIds
|
||||||
*/
|
*/
|
||||||
public SavingsAccount assembleFrom(final JsonCommand command) {
|
public SavingsAccount assembleFrom(final JsonCommand command, List<Long> existingTransactionIds,
|
||||||
|
List<Long> existingReversedTransactionIds) {
|
||||||
|
|
||||||
final JsonElement element = command.parsedJson();
|
final JsonElement element = command.parsedJson();
|
||||||
|
|
||||||
@@ -198,7 +203,7 @@ public class SavingsAccountAssembler {
|
|||||||
if (active) {
|
if (active) {
|
||||||
final Locale locale = command.extractLocale();
|
final Locale locale = command.extractLocale();
|
||||||
final DateTimeFormatter formatter = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
final DateTimeFormatter formatter = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||||
account.activate(formatter, activationDate);
|
account.activate(formatter, activationDate, existingTransactionIds, existingReversedTransactionIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
return account;
|
return account;
|
||||||
|
|||||||
+45
-6
@@ -7,6 +7,8 @@ package org.mifosplatform.portfolio.savings.domain;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
@@ -17,8 +19,12 @@ import javax.persistence.Temporal;
|
|||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
|
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
|
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionEnumData;
|
||||||
|
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
|
||||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,6 +40,10 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
|||||||
@JoinColumn(name = "savings_account_id", nullable = false)
|
@JoinColumn(name = "savings_account_id", nullable = false)
|
||||||
private SavingsAccount savingsAccount;
|
private SavingsAccount savingsAccount;
|
||||||
|
|
||||||
|
@ManyToOne(optional = true)
|
||||||
|
@JoinColumn(name = "payment_detail_id", nullable = true)
|
||||||
|
private PaymentDetail paymentDetail;
|
||||||
|
|
||||||
@Column(name = "transaction_type_enum", nullable = false)
|
@Column(name = "transaction_type_enum", nullable = false)
|
||||||
private final Integer typeOf;
|
private final Integer typeOf;
|
||||||
|
|
||||||
@@ -66,14 +76,18 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
|||||||
this.typeOf = null;
|
this.typeOf = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SavingsAccountTransaction deposit(final SavingsAccount savingsAccount, final LocalDate date, final Money amount) {
|
public static SavingsAccountTransaction deposit(final SavingsAccount savingsAccount, final PaymentDetail paymentDetail,
|
||||||
|
final LocalDate date, final Money amount) {
|
||||||
final boolean isReversed = false;
|
final boolean isReversed = false;
|
||||||
return new SavingsAccountTransaction(savingsAccount, SavingsAccountTransactionType.DEPOSIT.getValue(), date, amount, isReversed);
|
return new SavingsAccountTransaction(savingsAccount, paymentDetail, SavingsAccountTransactionType.DEPOSIT.getValue(), date, amount,
|
||||||
|
isReversed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SavingsAccountTransaction withdrawal(final SavingsAccount savingsAccount, final LocalDate date, final Money amount) {
|
public static SavingsAccountTransaction withdrawal(final SavingsAccount savingsAccount, final PaymentDetail paymentDetail,
|
||||||
|
final LocalDate date, final Money amount) {
|
||||||
final boolean isReversed = false;
|
final boolean isReversed = false;
|
||||||
return new SavingsAccountTransaction(savingsAccount, SavingsAccountTransactionType.WITHDRAWAL.getValue(), date, amount, isReversed);
|
return new SavingsAccountTransaction(savingsAccount, paymentDetail, SavingsAccountTransactionType.WITHDRAWAL.getValue(), date,
|
||||||
|
amount, isReversed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SavingsAccountTransaction interestPosting(final SavingsAccount savingsAccount, final LocalDate date, final Money amount) {
|
public static SavingsAccountTransaction interestPosting(final SavingsAccount savingsAccount, final LocalDate date, final Money amount) {
|
||||||
@@ -90,17 +104,23 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
public static SavingsAccountTransaction annualFee(final SavingsAccount savingsAccount, final LocalDate date, final Money amount) {
|
public static SavingsAccountTransaction annualFee(final SavingsAccount savingsAccount, final LocalDate date, final Money amount) {
|
||||||
final boolean isReversed = false;
|
final boolean isReversed = false;
|
||||||
return new SavingsAccountTransaction(savingsAccount, SavingsAccountTransactionType.ANNUAL_FEE.getValue(), date, amount,
|
return new SavingsAccountTransaction(savingsAccount, SavingsAccountTransactionType.ANNUAL_FEE.getValue(), date, amount, isReversed);
|
||||||
isReversed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Integer typeOf, final LocalDate transactionLocalDate,
|
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Integer typeOf, final LocalDate transactionLocalDate,
|
||||||
final Money amount, final boolean isReversed) {
|
final Money amount, final boolean isReversed) {
|
||||||
|
this(savingsAccount, null, typeOf, transactionLocalDate, amount, isReversed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final PaymentDetail paymentDetail, final Integer typeOf,
|
||||||
|
final LocalDate transactionLocalDate, final Money amount, final boolean isReversed) {
|
||||||
this.savingsAccount = savingsAccount;
|
this.savingsAccount = savingsAccount;
|
||||||
this.typeOf = typeOf;
|
this.typeOf = typeOf;
|
||||||
this.dateOf = transactionLocalDate.toDate();
|
this.dateOf = transactionLocalDate.toDate();
|
||||||
this.amount = amount.getAmount();
|
this.amount = amount.getAmount();
|
||||||
this.reversed = isReversed;
|
this.reversed = isReversed;
|
||||||
|
this.paymentDetail = paymentDetail;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate transactionLocalDate() {
|
public LocalDate transactionLocalDate() {
|
||||||
@@ -209,4 +229,23 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
|||||||
final Money transactionAmount = getAmount(amountToCheck.getCurrency());
|
final Money transactionAmount = getAmount(amountToCheck.getCurrency());
|
||||||
return transactionAmount.isNotEqualTo(amountToCheck);
|
return transactionAmount.isNotEqualTo(amountToCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> toMapData(final CurrencyData currencyData) {
|
||||||
|
final Map<String, Object> thisTransactionData = new LinkedHashMap<String, Object>();
|
||||||
|
|
||||||
|
final SavingsAccountTransactionEnumData transactionType = SavingsEnumerations.transactionType(this.typeOf);
|
||||||
|
|
||||||
|
thisTransactionData.put("id", this.getId());
|
||||||
|
thisTransactionData.put("type", transactionType);
|
||||||
|
thisTransactionData.put("reversed", Boolean.valueOf(this.isReversed()));
|
||||||
|
thisTransactionData.put("date", this.getTransactionLocalDate());
|
||||||
|
thisTransactionData.put("currency", currencyData);
|
||||||
|
thisTransactionData.put("amount", this.amount);
|
||||||
|
|
||||||
|
if (this.paymentDetail != null) {
|
||||||
|
thisTransactionData.put("paymentTypeId", this.paymentDetail.getPaymentType().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
return thisTransactionData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+33
-3
@@ -22,6 +22,7 @@ import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.namePa
|
|||||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.nominalAnnualInterestRateParamName;
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.nominalAnnualInterestRateParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.withdrawalFeeAmountParamName;
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.withdrawalFeeAmountParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.withdrawalFeeTypeParamName;
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.withdrawalFeeTypeParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.accountingRuleParamName;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -33,6 +34,7 @@ import javax.persistence.Entity;
|
|||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import org.joda.time.MonthDay;
|
import org.joda.time.MonthDay;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingRuleType;
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
import org.mifosplatform.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
||||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
@@ -93,6 +95,12 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
|||||||
@Column(name = "lockin_period_frequency_enum", nullable = true)
|
@Column(name = "lockin_period_frequency_enum", nullable = true)
|
||||||
private Integer lockinPeriodFrequencyType;
|
private Integer lockinPeriodFrequencyType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A value from the {@link AccountingRuleType} enumeration.
|
||||||
|
*/
|
||||||
|
@Column(name = "accounting_type", nullable = false)
|
||||||
|
private Integer accountingRule;
|
||||||
|
|
||||||
@Column(name = "withdrawal_fee_amount", scale = 6, precision = 19, nullable = true)
|
@Column(name = "withdrawal_fee_amount", scale = 6, precision = 19, nullable = true)
|
||||||
private BigDecimal withdrawalFeeAmount;
|
private BigDecimal withdrawalFeeAmount;
|
||||||
|
|
||||||
@@ -114,11 +122,11 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
|||||||
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||||
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
|
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
|
||||||
final BigDecimal withdrawalFeeAmount, final SavingsWithdrawalFeesType withdrawalFeeType, final BigDecimal annualFeeAmount,
|
final BigDecimal withdrawalFeeAmount, final SavingsWithdrawalFeesType withdrawalFeeType, final BigDecimal annualFeeAmount,
|
||||||
final MonthDay annualFeeOnMonthDay) {
|
final MonthDay annualFeeOnMonthDay, final AccountingRuleType accountingRuleType) {
|
||||||
|
|
||||||
return new SavingsProduct(name, description, currency, interestRate, interestCompoundingPeriodType, interestPostingPeriodType,
|
return new SavingsProduct(name, description, currency, interestRate, interestCompoundingPeriodType, interestPostingPeriodType,
|
||||||
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||||
lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType, annualFeeAmount, annualFeeOnMonthDay);
|
lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType, annualFeeAmount, annualFeeOnMonthDay, accountingRuleType);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SavingsProduct() {
|
protected SavingsProduct() {
|
||||||
@@ -132,7 +140,7 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
|||||||
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||||
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
|
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
|
||||||
final BigDecimal withdrawalFeeAmount, final SavingsWithdrawalFeesType withdrawalFeeType, final BigDecimal annualFeeAmount,
|
final BigDecimal withdrawalFeeAmount, final SavingsWithdrawalFeesType withdrawalFeeType, final BigDecimal annualFeeAmount,
|
||||||
final MonthDay annualFeeOnMonthDay) {
|
final MonthDay annualFeeOnMonthDay, final AccountingRuleType accountingRuleType) {
|
||||||
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
@@ -163,6 +171,10 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
|||||||
this.annualFeeOnDay = annualFeeOnMonthDay.getDayOfMonth();
|
this.annualFeeOnDay = annualFeeOnMonthDay.getDayOfMonth();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (accountingRuleType != null) {
|
||||||
|
this.accountingRule = accountingRuleType.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
validateLockinDetails();
|
validateLockinDetails();
|
||||||
validateWithdrawalFeeDetails();
|
validateWithdrawalFeeDetails();
|
||||||
validateAnnualFeeDetails();
|
validateAnnualFeeDetails();
|
||||||
@@ -356,6 +368,12 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
|||||||
this.annualFeeOnMonth = newValue;
|
this.annualFeeOnMonth = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (command.isChangeInIntegerParameterNamed(accountingRuleParamName, this.accountingRule)) {
|
||||||
|
final Integer newValue = command.integerValueOfParameterNamed(accountingRuleParamName);
|
||||||
|
actualChanges.put(accountingRuleParamName, newValue);
|
||||||
|
this.accountingRule = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
validateLockinDetails();
|
validateLockinDetails();
|
||||||
validateWithdrawalFeeDetails();
|
validateWithdrawalFeeDetails();
|
||||||
validateAnnualFeeDetails();
|
validateAnnualFeeDetails();
|
||||||
@@ -401,4 +419,16 @@ public class SavingsProduct extends AbstractPersistable<Long> {
|
|||||||
return (this.lockinPeriodFrequency == null && this.lockinPeriodFrequencyType != null)
|
return (this.lockinPeriodFrequency == null && this.lockinPeriodFrequencyType != null)
|
||||||
|| (this.lockinPeriodFrequencyType == null && this.lockinPeriodFrequency != null);
|
|| (this.lockinPeriodFrequencyType == null && this.lockinPeriodFrequency != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isCashBasedAccountingEnabled() {
|
||||||
|
return AccountingRuleType.CASH_BASED.getValue().equals(this.accountingRule);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAccrualBasedAccountingEnabled() {
|
||||||
|
return AccountingRuleType.ACCRUAL_BASED.getValue().equals(this.accountingRule);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getAccountingType() {
|
||||||
|
return this.accountingRule;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+3
-1
@@ -25,6 +25,7 @@ import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.withdr
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
import org.joda.time.MonthDay;
|
import org.joda.time.MonthDay;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingRuleType;
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -86,10 +87,11 @@ public class SavingsProductAssembler {
|
|||||||
|
|
||||||
final BigDecimal annualFeeAmount = command.bigDecimalValueOfParameterNamed(annualFeeAmountParamName);
|
final BigDecimal annualFeeAmount = command.bigDecimalValueOfParameterNamed(annualFeeAmountParamName);
|
||||||
final MonthDay monthDayOfAnnualFee = command.extractMonthDayNamed(annualFeeOnMonthDayParamName);
|
final MonthDay monthDayOfAnnualFee = command.extractMonthDayNamed(annualFeeOnMonthDayParamName);
|
||||||
|
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(command.integerValueOfParameterNamed("accountingRule"));
|
||||||
|
|
||||||
return SavingsProduct.createNew(name, description, currency, interestRate, interestCompoundingPeriodType,
|
return SavingsProduct.createNew(name, description, currency, interestRate, interestCompoundingPeriodType,
|
||||||
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||||
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType, annualFeeAmount,
|
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType, annualFeeAmount,
|
||||||
monthDayOfAnnualFee);
|
monthDayOfAnnualFee, accountingRuleType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+26
-2
@@ -12,6 +12,7 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.joda.time.MonthDay;
|
import org.joda.time.MonthDay;
|
||||||
|
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
||||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||||
@@ -22,6 +23,7 @@ import org.mifosplatform.portfolio.client.data.ClientData;
|
|||||||
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
||||||
import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
||||||
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
|
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
|
||||||
|
import org.mifosplatform.portfolio.paymentdetail.data.PaymentDetailData;
|
||||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountData;
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountData;
|
||||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountStatusEnumData;
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountStatusEnumData;
|
||||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountSummaryData;
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountSummaryData;
|
||||||
@@ -342,12 +344,17 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
|||||||
sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, ");
|
sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, ");
|
||||||
sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount,");
|
sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount,");
|
||||||
sqlBuilder.append("sa.id as savingsId, sa.account_no as accountNo, ");
|
sqlBuilder.append("sa.id as savingsId, sa.account_no as accountNo, ");
|
||||||
|
sqlBuilder.append("pd.payment_type_cv_id as paymentType,pd.account_number as accountNumber,pd.check_number as checkNumber, ");
|
||||||
|
sqlBuilder.append("pd.receipt_number as receiptNumber, pd.bank_number as bankNumber,pd.routing_code as routingCode, ");
|
||||||
sqlBuilder.append("sa.currency_code as currencyCode, sa.currency_digits as currencyDigits, ");
|
sqlBuilder.append("sa.currency_code as currencyCode, sa.currency_digits as currencyDigits, ");
|
||||||
sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
|
sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
|
||||||
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol ");
|
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
|
||||||
|
sqlBuilder.append("cv.code_value as paymentTypeName ");
|
||||||
sqlBuilder.append("from m_savings_account sa ");
|
sqlBuilder.append("from m_savings_account sa ");
|
||||||
sqlBuilder.append("join m_savings_account_transaction tr on tr.savings_account_id = sa.id ");
|
sqlBuilder.append("join m_savings_account_transaction tr on tr.savings_account_id = sa.id ");
|
||||||
sqlBuilder.append("join m_currency curr on curr.code = sa.currency_code ");
|
sqlBuilder.append("join m_currency curr on curr.code = sa.currency_code ");
|
||||||
|
sqlBuilder.append("left JOIN m_payment_detail pd ON tr.payment_detail_id = pd.id ");
|
||||||
|
sqlBuilder.append("left join m_code_value cv on pd.payment_type_cv_id = cv.id ");
|
||||||
|
|
||||||
this.schemaSql = sqlBuilder.toString();
|
this.schemaSql = sqlBuilder.toString();
|
||||||
}
|
}
|
||||||
@@ -368,6 +375,22 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
|||||||
final Long savingsId = rs.getLong("savingsId");
|
final Long savingsId = rs.getLong("savingsId");
|
||||||
final String accountNo = rs.getString("accountNo");
|
final String accountNo = rs.getString("accountNo");
|
||||||
|
|
||||||
|
PaymentDetailData paymentDetailData = null;
|
||||||
|
if (transactionType.isDepositOrWithdrawal()) {
|
||||||
|
final Long paymentTypeId = JdbcSupport.getLong(rs, "paymentType");
|
||||||
|
if (paymentTypeId != null) {
|
||||||
|
final String typeName = rs.getString("paymentTypeName");
|
||||||
|
CodeValueData paymentType = CodeValueData.instance(paymentTypeId, typeName);
|
||||||
|
final String accountNumber = rs.getString("accountNumber");
|
||||||
|
final String checkNumber = rs.getString("checkNumber");
|
||||||
|
final String routingCode = rs.getString("routingCode");
|
||||||
|
final String receiptNumber = rs.getString("receiptNumber");
|
||||||
|
final String bankNumber = rs.getString("bankNumber");
|
||||||
|
paymentDetailData = new PaymentDetailData(id, paymentType, accountNumber, checkNumber, routingCode, receiptNumber,
|
||||||
|
bankNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final String currencyCode = rs.getString("currencyCode");
|
final String currencyCode = rs.getString("currencyCode");
|
||||||
final String currencyName = rs.getString("currencyName");
|
final String currencyName = rs.getString("currencyName");
|
||||||
final String currencyNameCode = rs.getString("currencyNameCode");
|
final String currencyNameCode = rs.getString("currencyNameCode");
|
||||||
@@ -376,7 +399,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
|||||||
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
||||||
currencyNameCode);
|
currencyNameCode);
|
||||||
|
|
||||||
return SavingsAccountTransactionData.create(id, transactionType, savingsId, accountNo, date, currency, amount);
|
return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency,
|
||||||
|
amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+66
-6
@@ -6,19 +6,25 @@
|
|||||||
package org.mifosplatform.portfolio.savings.service;
|
package org.mifosplatform.portfolio.savings.service;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.joda.time.format.DateTimeFormat;
|
import org.joda.time.format.DateTimeFormat;
|
||||||
import org.joda.time.format.DateTimeFormatter;
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
|
import org.mifosplatform.accounting.journalentry.service.JournalEntryWritePlatformService;
|
||||||
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;
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||||
|
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
||||||
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator;
|
import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator;
|
||||||
import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory;
|
import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory;
|
||||||
import org.mifosplatform.portfolio.client.domain.Client;
|
import org.mifosplatform.portfolio.client.domain.Client;
|
||||||
@@ -26,6 +32,8 @@ import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
|||||||
import org.mifosplatform.portfolio.group.domain.Group;
|
import org.mifosplatform.portfolio.group.domain.Group;
|
||||||
import org.mifosplatform.portfolio.group.domain.GroupRepository;
|
import org.mifosplatform.portfolio.group.domain.GroupRepository;
|
||||||
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
|
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
|
||||||
|
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
|
import org.mifosplatform.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
|
||||||
import org.mifosplatform.portfolio.savings.api.SavingsApiConstants;
|
import org.mifosplatform.portfolio.savings.api.SavingsApiConstants;
|
||||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountDataValidator;
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountDataValidator;
|
||||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDataValidator;
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDataValidator;
|
||||||
@@ -59,6 +67,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
private final ClientRepositoryWrapper clientRepository;
|
private final ClientRepositoryWrapper clientRepository;
|
||||||
private final GroupRepository groupRepository;
|
private final GroupRepository groupRepository;
|
||||||
private final SavingsProductRepository savingsProductRepository;
|
private final SavingsProductRepository savingsProductRepository;
|
||||||
|
private final PaymentDetailWritePlatformService paymentDetailWritePlatformService;
|
||||||
|
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper;
|
||||||
|
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||||
@@ -67,7 +78,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
final SavingsAccountAssembler savingAccountAssembler, final SavingsAccountDataValidator savingsAccountDataValidator,
|
final SavingsAccountAssembler savingAccountAssembler, final SavingsAccountDataValidator savingsAccountDataValidator,
|
||||||
final SavingsAccountTransactionDataValidator savingsAccountTransactionDataValidator,
|
final SavingsAccountTransactionDataValidator savingsAccountTransactionDataValidator,
|
||||||
final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final ClientRepositoryWrapper clientRepository,
|
final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final ClientRepositoryWrapper clientRepository,
|
||||||
final GroupRepository groupRepository, final SavingsProductRepository savingsProductRepository) {
|
final GroupRepository groupRepository, final SavingsProductRepository savingsProductRepository,
|
||||||
|
final PaymentDetailWritePlatformService paymentDetailWritePlatformService,
|
||||||
|
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
|
||||||
|
final JournalEntryWritePlatformService journalEntryWritePlatformService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.savingAccountRepository = savingAccountRepository;
|
this.savingAccountRepository = savingAccountRepository;
|
||||||
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
|
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
|
||||||
@@ -78,6 +92,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
this.clientRepository = clientRepository;
|
this.clientRepository = clientRepository;
|
||||||
this.groupRepository = groupRepository;
|
this.groupRepository = groupRepository;
|
||||||
this.savingsProductRepository = savingsProductRepository;
|
this.savingsProductRepository = savingsProductRepository;
|
||||||
|
this.paymentDetailWritePlatformService = paymentDetailWritePlatformService;
|
||||||
|
this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper;
|
||||||
|
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -115,7 +132,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
this.savingsAccountDataValidator.validateForCreate(command.json());
|
this.savingsAccountDataValidator.validateForCreate(command.json());
|
||||||
|
|
||||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(command);
|
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||||
|
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
||||||
|
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(command, existingTransactionIds,
|
||||||
|
existingReversedTransactionIds);
|
||||||
this.savingAccountRepository.save(account);
|
this.savingAccountRepository.save(account);
|
||||||
|
|
||||||
if (account.isAccountNumberRequiresAutoGeneration()) {
|
if (account.isAccountNumberRequiresAutoGeneration()) {
|
||||||
@@ -126,6 +146,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
this.savingAccountRepository.save(account);
|
this.savingAccountRepository.save(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
final Long savingsId = account.getId();
|
final Long savingsId = account.getId();
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
@@ -237,10 +259,15 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
final Locale locale = command.extractLocale();
|
final Locale locale = command.extractLocale();
|
||||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||||
final LocalDate activationDate = command.localDateValueOfParameterNamed("activationDate");
|
final LocalDate activationDate = command.localDateValueOfParameterNamed("activationDate");
|
||||||
account.activate(fmt, activationDate);
|
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||||
|
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
||||||
|
|
||||||
|
account.activate(fmt, activationDate, existingReversedTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
this.savingAccountRepository.save(account);
|
this.savingAccountRepository.save(account);
|
||||||
|
|
||||||
|
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withEntityId(savingsId) //
|
.withEntityId(savingsId) //
|
||||||
.withOfficeId(account.officeId()) //
|
.withOfficeId(account.officeId()) //
|
||||||
@@ -266,17 +293,26 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||||
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
|
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
|
||||||
|
|
||||||
final SavingsAccountTransaction deposit = account.deposit(fmt, transactionDate, transactionAmount);
|
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||||
|
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
||||||
|
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||||
|
PaymentDetail paymentDetail = paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
||||||
|
|
||||||
|
final SavingsAccountTransaction deposit = account.deposit(fmt, transactionDate, transactionAmount, existingTransactionIds,
|
||||||
|
existingReversedTransactionIds, paymentDetail);
|
||||||
final Long transactionId = saveTransactionToGenerateTransactionId(deposit);
|
final Long transactionId = saveTransactionToGenerateTransactionId(deposit);
|
||||||
|
|
||||||
this.savingAccountRepository.save(account);
|
this.savingAccountRepository.save(account);
|
||||||
|
|
||||||
|
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withEntityId(transactionId) //
|
.withEntityId(transactionId) //
|
||||||
.withOfficeId(account.officeId()) //
|
.withOfficeId(account.officeId()) //
|
||||||
.withClientId(account.clientId()) //
|
.withClientId(account.clientId()) //
|
||||||
.withGroupId(account.groupId()) //
|
.withGroupId(account.groupId()) //
|
||||||
.withSavingsId(savingsId) //
|
.withSavingsId(savingsId) //
|
||||||
|
.with(changes)//
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,16 +337,25 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
final Locale locale = command.extractLocale();
|
final Locale locale = command.extractLocale();
|
||||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||||
|
|
||||||
final SavingsAccountTransaction withdrawal = account.withdraw(fmt, transactionDate, transactionAmount);
|
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||||
|
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
||||||
|
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||||
|
PaymentDetail paymentDetail = paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
||||||
|
|
||||||
|
final SavingsAccountTransaction withdrawal = account.withdraw(fmt, transactionDate, transactionAmount, existingTransactionIds,
|
||||||
|
existingReversedTransactionIds, paymentDetail);
|
||||||
final Long transactionId = saveTransactionToGenerateTransactionId(withdrawal);
|
final Long transactionId = saveTransactionToGenerateTransactionId(withdrawal);
|
||||||
this.savingAccountRepository.save(account);
|
this.savingAccountRepository.save(account);
|
||||||
|
|
||||||
|
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withEntityId(transactionId) //
|
.withEntityId(transactionId) //
|
||||||
.withOfficeId(account.officeId()) //
|
.withOfficeId(account.officeId()) //
|
||||||
.withClientId(account.clientId()) //
|
.withClientId(account.clientId()) //
|
||||||
.withGroupId(account.groupId()) //
|
.withGroupId(account.groupId()) //
|
||||||
.withSavingsId(savingsId) //
|
.withSavingsId(savingsId) //
|
||||||
|
.with(changes)//
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,13 +382,17 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
@Override
|
@Override
|
||||||
public CommandProcessingResult postInterest(final Long savingsId, final JsonCommand command) {
|
public CommandProcessingResult postInterest(final Long savingsId, final JsonCommand command) {
|
||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
|
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||||
|
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
||||||
|
|
||||||
final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(savingsId);
|
final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(savingsId);
|
||||||
|
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||||
account.postInterest(today);
|
account.postInterest(today, existingTransactionIds, existingReversedTransactionIds);
|
||||||
this.savingAccountRepository.save(account);
|
this.savingAccountRepository.save(account);
|
||||||
|
|
||||||
|
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withEntityId(savingsId) //
|
.withEntityId(savingsId) //
|
||||||
.withOfficeId(account.officeId()) //
|
.withOfficeId(account.officeId()) //
|
||||||
@@ -352,4 +401,15 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
.withSavingsId(savingsId) //
|
.withSavingsId(savingsId) //
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void postJournalEntries(final SavingsAccount savingsAccount, final List<Long> existingTransactionIds,
|
||||||
|
final List<Long> existingReversedTransactionIds) {
|
||||||
|
|
||||||
|
final MonetaryCurrency currency = savingsAccount.getCurrency();
|
||||||
|
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepositoryWrapper.findOneWithNotFoundDetection(currency);
|
||||||
|
|
||||||
|
final Map<String, Object> accountingBridgeData = savingsAccount.deriveAccountingBridgeData(applicationCurrency.toData(),
|
||||||
|
existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
journalEntryWritePlatformService.createJournalEntriesForSavings(accountingBridgeData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+7
-2
@@ -11,6 +11,7 @@ import java.sql.SQLException;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.joda.time.MonthDay;
|
import org.joda.time.MonthDay;
|
||||||
|
import org.mifosplatform.accounting.common.AccountingEnumerations;
|
||||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||||
@@ -89,7 +90,8 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
|
|||||||
sqlBuilder.append("sp.withdrawal_fee_type_enum as withdrawalFeeTypeEnum, ");
|
sqlBuilder.append("sp.withdrawal_fee_type_enum as withdrawalFeeTypeEnum, ");
|
||||||
sqlBuilder.append("sp.annual_fee_amount as annualFeeAmount,");
|
sqlBuilder.append("sp.annual_fee_amount as annualFeeAmount,");
|
||||||
sqlBuilder.append("sp.annual_fee_on_month as annualFeeOnMonth, ");
|
sqlBuilder.append("sp.annual_fee_on_month as annualFeeOnMonth, ");
|
||||||
sqlBuilder.append("sp.annual_fee_on_day as annualFeeOnDay ");
|
sqlBuilder.append("sp.annual_fee_on_day as annualFeeOnDay, ");
|
||||||
|
sqlBuilder.append("sp.accounting_type as accountingType ");
|
||||||
sqlBuilder.append("from m_savings_product sp ");
|
sqlBuilder.append("from m_savings_product sp ");
|
||||||
sqlBuilder.append("join m_currency curr on curr.code = sp.currency_code ");
|
sqlBuilder.append("join m_currency curr on curr.code = sp.currency_code ");
|
||||||
|
|
||||||
@@ -134,6 +136,9 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
|
|||||||
.interestCalculationDaysInYearType(interestCalculationDaysInYearTypeValue);
|
.interestCalculationDaysInYearType(interestCalculationDaysInYearTypeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Integer accountingRuleId = JdbcSupport.getInteger(rs, "accountingType");
|
||||||
|
final EnumOptionData accountingRuleType = AccountingEnumerations.accountingRuleType(accountingRuleId);
|
||||||
|
|
||||||
final BigDecimal minRequiredOpeningBalance = rs.getBigDecimal("minRequiredOpeningBalance");
|
final BigDecimal minRequiredOpeningBalance = rs.getBigDecimal("minRequiredOpeningBalance");
|
||||||
|
|
||||||
Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockinPeriodFrequency");
|
Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockinPeriodFrequency");
|
||||||
@@ -163,7 +168,7 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
|
|||||||
return SavingsProductData.instance(id, name, description, currency, nominalAnnualInterestRate, compoundingInterestPeriodType,
|
return SavingsProductData.instance(id, name, description, currency, nominalAnnualInterestRate, compoundingInterestPeriodType,
|
||||||
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
|
||||||
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType, annualFeeAmount,
|
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeAmount, withdrawalFeeType, annualFeeAmount,
|
||||||
annualFeeOnMonthDay);
|
annualFeeOnMonthDay, accountingRuleType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-1
@@ -7,6 +7,7 @@ package org.mifosplatform.portfolio.savings.service;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.mifosplatform.accounting.producttoaccountmapping.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;
|
||||||
@@ -23,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.accountingRuleParamName;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class SavingsProductWritePlatformServiceJpaRepositoryImpl implements SavingsProductWritePlatformService {
|
public class SavingsProductWritePlatformServiceJpaRepositoryImpl implements SavingsProductWritePlatformService {
|
||||||
@@ -32,16 +34,19 @@ public class SavingsProductWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
private final SavingsProductRepository savingProductRepository;
|
private final SavingsProductRepository savingProductRepository;
|
||||||
private final SavingsProductDataValidator fromApiJsonDataValidator;
|
private final SavingsProductDataValidator fromApiJsonDataValidator;
|
||||||
private final SavingsProductAssembler savingsProductAssembler;
|
private final SavingsProductAssembler savingsProductAssembler;
|
||||||
|
private final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public SavingsProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
public SavingsProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||||
final SavingsProductRepository savingProductRepository, final SavingsProductDataValidator fromApiJsonDataValidator,
|
final SavingsProductRepository savingProductRepository, final SavingsProductDataValidator fromApiJsonDataValidator,
|
||||||
final SavingsProductAssembler savingsProductAssembler) {
|
final SavingsProductAssembler savingsProductAssembler,
|
||||||
|
final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.savingProductRepository = savingProductRepository;
|
this.savingProductRepository = savingProductRepository;
|
||||||
this.fromApiJsonDataValidator = fromApiJsonDataValidator;
|
this.fromApiJsonDataValidator = fromApiJsonDataValidator;
|
||||||
this.savingsProductAssembler = savingsProductAssembler;
|
this.savingsProductAssembler = savingsProductAssembler;
|
||||||
this.logger = LoggerFactory.getLogger(SavingsProductWritePlatformServiceJpaRepositoryImpl.class);
|
this.logger = LoggerFactory.getLogger(SavingsProductWritePlatformServiceJpaRepositoryImpl.class);
|
||||||
|
this.accountMappingWritePlatformService = accountMappingWritePlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -78,6 +83,9 @@ public class SavingsProductWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
|
|
||||||
this.savingProductRepository.save(product);
|
this.savingProductRepository.save(product);
|
||||||
|
|
||||||
|
// save accounting mappings
|
||||||
|
accountMappingWritePlatformService.createSavingProductToGLAccountMapping(product.getId(), command);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withEntityId(product.getId()) //
|
.withEntityId(product.getId()) //
|
||||||
.build();
|
.build();
|
||||||
@@ -99,6 +107,13 @@ public class SavingsProductWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
if (product == null) { throw new SavingsProductNotFoundException(productId); }
|
if (product == null) { throw new SavingsProductNotFoundException(productId); }
|
||||||
|
|
||||||
final Map<String, Object> changes = product.update(command);
|
final Map<String, Object> changes = product.update(command);
|
||||||
|
|
||||||
|
// accounting related changes
|
||||||
|
boolean accountingTypeChanged = changes.containsKey(accountingRuleParamName);
|
||||||
|
final Map<String, Object> accountingMappingChanges = accountMappingWritePlatformService.updateSavingsProductToGLAccountMapping(
|
||||||
|
product.getId(), command, accountingTypeChanged, product.getAccountingType());
|
||||||
|
changes.putAll(accountingMappingChanges);
|
||||||
|
|
||||||
if (!changes.isEmpty()) {
|
if (!changes.isEmpty()) {
|
||||||
this.savingProductRepository.saveAndFlush(product);
|
this.savingProductRepository.saveAndFlush(product);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user