This is an automated email from the ASF dual-hosted git repository.

avikg pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 32fae2b  FINERACT-1410 :Allow Payment types to map to all types of 
Ledgers (#1894)
32fae2b is described below

commit 32fae2b1274e494c9b53ceefbbc997931c685b7e
Author: ankita10r <[email protected]>
AuthorDate: Tue Oct 19 19:23:53 2021 +0530

    FINERACT-1410 :Allow Payment types to map to all types of Ledgers (#1894)
---
 .../service/ProductToGLAccountMappingHelper.java   |  8 ++++--
 .../api/GlobalConfigurationApiConstant.java        |  1 +
 .../data/GlobalConfigurationDataValidator.java     | 12 ++++++---
 .../data/GlobalConfigurationPropertyData.java      | 13 +++++++---
 .../domain/ConfigurationDomainService.java         |  4 +++
 .../domain/ConfigurationDomainServiceJpa.java      | 30 ++++++++++++++++++++++
 .../domain/GlobalConfigurationProperty.java        | 24 ++++++++++++++---
 .../ConfigurationReadPlatformServiceImpl.java      | 11 ++++----
 .../portfolio/savings/SavingsApiConstants.java     |  2 ++
 .../savings/api/SavingsApiSetConstants.java        |  5 ++--
 .../savings/api/SavingsProductsApiResource.java    | 17 ++++++++----
 .../api/SavingsProductsApiResourceSwagger.java     |  4 +++
 .../portfolio/savings/data/SavingsProductData.java | 25 +++++++++++-------
 ..._adding_expenseliablity_to_paymentorfeetype.sql | 25 ++++++++++++++++++
 14 files changed, 147 insertions(+), 34 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
index 2db50c5..2e44ad9 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
@@ -362,8 +362,7 @@ public class ProductToGLAccountMappingHelper {
     private void savePaymentChannelToFundSourceMapping(final Long productId, 
final Long paymentTypeId,
             final Long paymentTypeSpecificFundAccountId, final 
PortfolioProductType portfolioProductType) {
         final PaymentType paymentType = 
this.paymentTypeRepositoryWrapper.findOneWithNotFoundDetection(paymentTypeId);
-        final GLAccount glAccount = 
getAccountByIdAndType(LoanProductAccountingParams.FUND_SOURCE.getValue(), 
GLAccountType.ASSET,
-                paymentTypeSpecificFundAccountId);
+        final GLAccount glAccount = 
getAccountById(LoanProductAccountingParams.FUND_SOURCE.getValue(), 
paymentTypeSpecificFundAccountId);
         final ProductToGLAccountMapping accountMapping = new 
ProductToGLAccountMapping(glAccount, productId,
                 portfolioProductType.getValue(), 
CashAccountsForLoan.FUND_SOURCE.getValue(), paymentType);
         this.accountMappingRepository.save(accountMapping);
@@ -427,6 +426,11 @@ public class ProductToGLAccountMappingHelper {
         return glAccount;
     }
 
+    public GLAccount getAccountById(final String paramName, final Long 
accountId) {
+        final GLAccount glAccount = 
this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountId);
+        return glAccount;
+    }
+
     public GLAccount getAccountByIdAndType(final String paramName, final 
List<GLAccountType> expectedAccountTypes, final Long accountId) {
         final GLAccount glAccount = 
this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountId);
         // validate account is of the expected Type
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/api/GlobalConfigurationApiConstant.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/api/GlobalConfigurationApiConstant.java
index 3174b45..b8e86d5 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/api/GlobalConfigurationApiConstant.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/api/GlobalConfigurationApiConstant.java
@@ -31,5 +31,6 @@ public final class GlobalConfigurationApiConstant {
     public static final String CONFIGURATION_RESOURCE_NAME = 
"globalConfiguration";
     public static final String localeParamName = "locale";
     public static final String dateFormatParamName = "dateFormat";
+    public static final String STRING_VALUE = "stringValue";
 
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/data/GlobalConfigurationDataValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/data/GlobalConfigurationDataValidator.java
index 40676ed..668d619 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/data/GlobalConfigurationDataValidator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/data/GlobalConfigurationDataValidator.java
@@ -43,9 +43,10 @@ import org.springframework.stereotype.Component;
 public class GlobalConfigurationDataValidator {
 
     private final FromJsonHelper fromApiJsonHelper;
-    private static final Set<String> UPDATE_CONFIGURATION_DATA_PARAMETERS = 
new HashSet<>(Arrays.asList(
-            GlobalConfigurationApiConstant.localeParamName, 
GlobalConfigurationApiConstant.dateFormatParamName,
-            GlobalConfigurationApiConstant.ENABLED, 
GlobalConfigurationApiConstant.VALUE, 
GlobalConfigurationApiConstant.DATE_VALUE));
+    private static final Set<String> UPDATE_CONFIGURATION_DATA_PARAMETERS = 
new HashSet<>(
+            Arrays.asList(GlobalConfigurationApiConstant.localeParamName, 
GlobalConfigurationApiConstant.dateFormatParamName,
+                    GlobalConfigurationApiConstant.ENABLED, 
GlobalConfigurationApiConstant.VALUE, GlobalConfigurationApiConstant.DATE_VALUE,
+                    GlobalConfigurationApiConstant.STRING_VALUE));
 
     @Autowired
     public GlobalConfigurationDataValidator(final FromJsonHelper 
fromApiJsonHelper) {
@@ -81,6 +82,11 @@ public class GlobalConfigurationDataValidator {
             
baseDataValidator.reset().parameter(GlobalConfigurationApiConstant.DATE_VALUE).value(dateValue).notNull();
         }
 
+        if 
(this.fromApiJsonHelper.parameterExists(GlobalConfigurationApiConstant.STRING_VALUE,
 element)) {
+            final String stringValue = 
this.fromApiJsonHelper.extractStringNamed(GlobalConfigurationApiConstant.STRING_VALUE,
 element);
+            
baseDataValidator.reset().parameter(GlobalConfigurationApiConstant.STRING_VALUE).value(stringValue).notNull();
+        }
+
         if (!dataValidationErrors.isEmpty()) {
             throw new PlatformApiDataValidationException(dataValidationErrors);
         }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/data/GlobalConfigurationPropertyData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/data/GlobalConfigurationPropertyData.java
index a893b93..7e54b01 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/data/GlobalConfigurationPropertyData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/data/GlobalConfigurationPropertyData.java
@@ -33,6 +33,7 @@ public class GlobalConfigurationPropertyData {
     private final Long value;
     @SuppressWarnings("unused")
     private final Date dateValue;
+    private String stringValue;
     @SuppressWarnings("unused")
     private final Long id;
     @SuppressWarnings("unused")
@@ -41,22 +42,24 @@ public class GlobalConfigurationPropertyData {
     private final boolean trapDoor;
 
     public GlobalConfigurationPropertyData(final String name, final boolean 
enabled, final Long value, final Date dateValue,
-            final String description, final boolean trapDoor) {
+            final String stringValue, final String description, final boolean 
trapDoor) {
         this.name = name;
         this.enabled = enabled;
         this.value = value;
         this.dateValue = dateValue;
+        this.stringValue = stringValue;
         this.id = null;
         this.description = description;
         this.trapDoor = trapDoor;
     }
 
-    public GlobalConfigurationPropertyData(final String name, final boolean 
enabled, final Long value, Date dateValue, final Long id,
-            final String description, final boolean isTrapDoor) {
+    public GlobalConfigurationPropertyData(final String name, final boolean 
enabled, final Long value, Date dateValue,
+            final String stringValue, final Long id, final String description, 
final boolean isTrapDoor) {
         this.name = name;
         this.enabled = enabled;
         this.value = value;
         this.dateValue = dateValue;
+        this.stringValue = stringValue;
         this.id = id;
         this.description = description;
         this.trapDoor = isTrapDoor;
@@ -74,6 +77,10 @@ public class GlobalConfigurationPropertyData {
         return this.value;
     }
 
+    public String getStringValue() {
+        return this.stringValue;
+    }
+
     public Date getDateValue() {
         return this.dateValue;
     }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainService.java
index 4b791c9..b35611c 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainService.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainService.java
@@ -98,4 +98,8 @@ public interface ConfigurationDomainService {
     boolean isFirstRepaymentDateAfterRescheduleAllowedOnHoliday();
 
     boolean isInterestToBeAppropriatedEquallyWhenGreaterThanEMI();
+
+    String getAccountMappingForPaymentType();
+
+    String getAccountMappingForCharge();
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
index 321d640..b03c2a9 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
@@ -363,4 +363,34 @@ public class ConfigurationDomainServiceJpa implements 
ConfigurationDomainService
         }
     }
 
+    @Override
+    public String getAccountMappingForPaymentType() {
+        final String propertyName = "account-mapping-for-payment-type";
+        String defaultValue = "Asset"; // 1 Stands for Account mapped from 
asset only
+        final GlobalConfigurationPropertyData property = 
getGlobalConfigurationPropertyData(propertyName);
+        if (property.isEnabled()) {
+            String value = property.getStringValue();
+            if (value == null) {
+                return defaultValue;
+            }
+            return value;
+        }
+        return defaultValue;
+    }
+
+    @Override
+    public String getAccountMappingForCharge() {
+        final String propertyName = "account-mapping-for-charge";
+        String defaultValue = "Income"; // 1 Stands for Account mapped from 
income only
+        final GlobalConfigurationPropertyData property = 
getGlobalConfigurationPropertyData(propertyName);
+        if (property.isEnabled()) {
+            String value = property.getValue().toString();
+            if (value == null) {
+                return defaultValue;
+            }
+            return value;
+        }
+        return defaultValue;
+    }
+
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java
index e6a3a2e..84e0283 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java
@@ -46,6 +46,9 @@ public class GlobalConfigurationProperty extends 
AbstractPersistableCustom {
     @Column(name = "date_value", nullable = true)
     private Date dateValue;
 
+    @Column(name = "string_value", nullable = true)
+    private String stringValue;
+
     @Column(name = "description", nullable = true)
     private String description;
 
@@ -57,16 +60,18 @@ public class GlobalConfigurationProperty extends 
AbstractPersistableCustom {
         this.enabled = false;
         this.value = null;
         this.dateValue = null;
+        this.stringValue = null;
         this.description = null;
         this.isTrapDoor = false;
     }
 
     public GlobalConfigurationProperty(final String name, final boolean 
enabled, final Long value, final Date dateValue,
-            final String description, final boolean isTrapDoor) {
+            final String stringValue, final String description, final boolean 
isTrapDoor) {
         this.name = name;
         this.enabled = enabled;
         this.value = value;
         this.dateValue = dateValue;
+        this.stringValue = stringValue;
         this.description = description;
         this.isTrapDoor = isTrapDoor;
     }
@@ -83,6 +88,10 @@ public class GlobalConfigurationProperty extends 
AbstractPersistableCustom {
         return this.dateValue;
     }
 
+    public String getStringValue() {
+        return this.stringValue;
+    }
+
     public Map<String, Object> update(final JsonCommand command) {
 
         final Map<String, Object> actualChanges = new LinkedHashMap<>(7);
@@ -113,6 +122,13 @@ public class GlobalConfigurationProperty extends 
AbstractPersistableCustom {
             this.dateValue = newDateValue;
         }
 
+        final String stringValueParamName = "stringValue";
+        if (command.isChangeInStringParameterNamed(stringValueParamName, 
this.stringValue)) {
+            final String newStringValue = 
command.stringValueOfParameterNamed(stringValueParamName);
+            actualChanges.put(stringValueParamName, newStringValue);
+            this.stringValue = newStringValue;
+        }
+
         final String passwordPropertyName = "force-password-reset-days";
         if (this.name.equalsIgnoreCase(passwordPropertyName)) {
             if ((this.enabled == true && command.hasParameter(valueParamName) 
&& (this.value == 0))
@@ -126,12 +142,12 @@ public class GlobalConfigurationProperty extends 
AbstractPersistableCustom {
     }
 
     public static GlobalConfigurationProperty newSurveyConfiguration(final 
String name) {
-        return new GlobalConfigurationProperty(name, false, null, null, null, 
false);
+        return new GlobalConfigurationProperty(name, false, null, null, null, 
null, false);
     }
 
     public GlobalConfigurationPropertyData toData() {
-        return new GlobalConfigurationPropertyData(getName(), isEnabled(), 
getValue(), getDateValue(), this.getId(), this.description,
-                this.isTrapDoor);
+        return new GlobalConfigurationPropertyData(getName(), isEnabled(), 
getValue(), getDateValue(), getStringValue(), this.getId(),
+                this.description, this.isTrapDoor);
     }
 
     public String getName() {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java
index 65eaec1..dd7326a 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java
@@ -52,7 +52,7 @@ public class ConfigurationReadPlatformServiceImpl implements 
ConfigurationReadPl
 
         this.context.authenticatedUser();
 
-        String sql = "SELECT c.id, c.name, c.enabled, c.value, c.date_value, 
c.description, c.is_trap_door FROM c_configuration c ";
+        String sql = "SELECT c.id, c.name, c.enabled, c.value, c.date_value, 
c.description,c.string_value, c.is_trap_door FROM c_configuration c ";
 
         if (survey) {
             sql += " JOIN x_registered_table on 
x_registered_table.registered_table_name = c.name ";
@@ -68,11 +68,11 @@ public class ConfigurationReadPlatformServiceImpl 
implements ConfigurationReadPl
     }
 
     @Override
-    public GlobalConfigurationPropertyData retrieveGlobalConfiguration(String 
name) {
+    public GlobalConfigurationPropertyData retrieveGlobalConfiguration(final 
String name) {
 
         this.context.authenticatedUser();
 
-        final String sql = "SELECT c.id, c.name, c.enabled, c.value, 
c.date_value, c.description, c.is_trap_door FROM "
+        final String sql = "SELECT c.id, c.name, c.enabled, c.value, 
c.date_value, c.string_value, c.description, c.is_trap_door FROM "
                 + "c_configuration c where c.name=? order by c.id";
         final GlobalConfigurationPropertyData globalConfiguration = 
this.jdbcTemplate.queryForObject(sql, this.rm, new Object[] { name });
 
@@ -84,7 +84,7 @@ public class ConfigurationReadPlatformServiceImpl implements 
ConfigurationReadPl
 
         this.context.authenticatedUser();
 
-        final String sql = "SELECT c.id, c.name, c.enabled, c.value, 
c.date_value, c.description, c.is_trap_door FROM "
+        final String sql = "SELECT c.id, c.name, c.enabled, c.value, 
c.date_value, c.string_value ,c.description, c.is_trap_door FROM "
                 + "c_configuration c where c.id=? order by c.id";
         final GlobalConfigurationPropertyData globalConfiguration = 
this.jdbcTemplate.queryForObject(sql, this.rm,
                 new Object[] { configId });
@@ -102,10 +102,11 @@ public class ConfigurationReadPlatformServiceImpl 
implements ConfigurationReadPl
             final boolean enabled = rs.getBoolean("enabled");
             final Long value = rs.getLong("value");
             final Date dateValue = rs.getDate("date_value");
+            final String stringValue = rs.getString("string_value");
             final String description = rs.getString("description");
             final Long id = rs.getLong("id");
             final boolean isTrapDoor = rs.getBoolean("is_trap_door");
-            return new GlobalConfigurationPropertyData(name, enabled, value, 
dateValue, id, description, isTrapDoor);
+            return new GlobalConfigurationPropertyData(name, enabled, value, 
dateValue, stringValue, id, description, isTrapDoor);
         }
     }
 
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java
index 8f2e884..1113571 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java
@@ -191,4 +191,6 @@ public class SavingsApiConstants {
     public static final String gsimApplicationId = "applicationId";
     public static final String gsimLastApplication = "lastApplication";
     public static final String ERROR_MSG_SAVINGS_ACCOUNT_NOT_ACTIVE = 
"not.in.active.state";
+
+    public static final String accountMappingForPaymentParamName = 
"accountMappingForPayment";
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsApiSetConstants.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsApiSetConstants.java
index 3ec70e7..d278167 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsApiSetConstants.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsApiSetConstants.java
@@ -41,13 +41,12 @@ public class SavingsApiSetConstants extends 
SavingsApiConstants {
                     "interestCalculationTypeOptions", 
"interestCalculationDaysInYearTypeOptions", "lockinPeriodFrequencyTypeOptions",
                     "withdrawalFeeTypeOptions", 
nominalAnnualInterestRateOverdraftParamName, 
minOverdraftForInterestCalculationParamName,
                     withHoldTaxParamName, taxGroupIdParamName, 
isDormancyTrackingActiveParamName, daysToInactiveParamName,
-                    daysToDormancyParamName, daysToInactiveParamName));
+                    daysToDormancyParamName, daysToInactiveParamName, 
accountMappingForPaymentParamName));
 
     /**
      * These parameters will match the class level parameters of {@link 
SavingsAccountData}. Where possible, we try to
      * get response parameters to match those of request parameters.
      */
-
     protected static final Set<String> 
SAVINGS_ACCOUNT_RESPONSE_DATA_PARAMETERS = new 
HashSet<>(Arrays.asList(idParamName,
             accountNoParamName, externalIdParamName, statusParamName, 
activatedOnDateParamName, staffIdParamName, clientIdParamName,
             "clientName", groupIdParamName, "groupName", "savingsProductId", 
"savingsProductName", "currency",
@@ -58,7 +57,7 @@ public class SavingsApiSetConstants extends 
SavingsApiConstants {
             "interestCompoundingPeriodTypeOptions", 
"interestPostingPeriodTypeOptions", "interestCalculationTypeOptions",
             "interestCalculationDaysInYearTypeOptions", 
"lockinPeriodFrequencyTypeOptions", "withdrawalFeeTypeOptions", "withdrawalFee",
             "annualFee", onHoldFundsParamName, 
nominalAnnualInterestRateOverdraftParamName, 
minOverdraftForInterestCalculationParamName,
-            datatables, savingsAmountOnHold));
+            datatables, savingsAmountOnHold, 
accountMappingForPaymentParamName));
 
     protected static final Set<String> 
SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<>(
             Arrays.asList(idParamName, "accountId", accountNoParamName, 
"currency", "amount", dateParamName, paymentDetailDataParamName,
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsProductsApiResource.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsProductsApiResource.java
index ab8d4c2..d01f4dc 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsProductsApiResource.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsProductsApiResource.java
@@ -52,6 +52,7 @@ import 
org.apache.fineract.accounting.producttoaccountmapping.service.ProductToG
 import org.apache.fineract.commands.domain.CommandWrapper;
 import org.apache.fineract.commands.service.CommandWrapperBuilder;
 import 
org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import 
org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
 import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
 import org.apache.fineract.infrastructure.core.data.EnumOptionData;
@@ -100,6 +101,7 @@ public class SavingsProductsApiResource {
     private final ChargeReadPlatformService chargeReadPlatformService;
     private final PaymentTypeReadPlatformService 
paymentTypeReadPlatformService;
     private final TaxReadPlatformService taxReadPlatformService;
+    private final ConfigurationDomainService configurationDomainService;
 
     @Autowired
     public SavingsProductsApiResource(final SavingsProductReadPlatformService 
savingProductReadPlatformService,
@@ -111,7 +113,7 @@ public class SavingsProductsApiResource {
             final AccountingDropdownReadPlatformService 
accountingDropdownReadPlatformService,
             final ProductToGLAccountMappingReadPlatformService 
accountMappingReadPlatformService,
             final ChargeReadPlatformService chargeReadPlatformService, 
PaymentTypeReadPlatformService paymentTypeReadPlatformService,
-            final TaxReadPlatformService taxReadPlatformService) {
+            final TaxReadPlatformService taxReadPlatformService, final 
ConfigurationDomainService configurationDomainService) {
         this.savingProductReadPlatformService = 
savingProductReadPlatformService;
         this.dropdownReadPlatformService = dropdownReadPlatformService;
         this.currencyReadPlatformService = currencyReadPlatformService;
@@ -124,6 +126,7 @@ public class SavingsProductsApiResource {
         this.chargeReadPlatformService = chargeReadPlatformService;
         this.paymentTypeReadPlatformService = paymentTypeReadPlatformService;
         this.taxReadPlatformService = taxReadPlatformService;
+        this.configurationDomainService = configurationDomainService;
     }
 
     @POST
@@ -132,7 +135,7 @@ public class SavingsProductsApiResource {
     @Operation(summary = "Create a Savings Product", description = "Creates a 
Savings Product\n\n"
             + "Mandatory Fields: name, shortName, description, currencyCode, 
digitsAfterDecimal,inMultiplesOf, nominalAnnualInterestRate, 
interestCompoundingPeriodType, interestCalculationType, 
interestCalculationDaysInYearType,accountingRule\n\n"
             + "Mandatory Fields for Cash based accounting (accountingRule = 
2): savingsReferenceAccountId, savingsControlAccountId, 
interestOnSavingsAccountId, incomeFromFeeAccountId, 
transfersInSuspenseAccountId, incomeFromPenaltyAccountId\n\n"
-            + "Optional Fields: minRequiredOpeningBalance, 
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, 
paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, 
penaltyToIncomeAccountMappings, charges, allowOverdraft, overdraftLimit, 
minBalanceForInterestCalculation,withHoldTax,taxGroupId")
+            + "Optional Fields: minRequiredOpeningBalance, 
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, 
paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, 
penaltyToIncomeAccountMappings, charges, allowOverdraft, overdraftLimit, 
minBalanceForInterestCalculation,withHoldTax,taxGroupId,accountMapping")
     @RequestBody(required = true, content = @Content(schema = 
@Schema(implementation = 
SavingsProductsApiResourceSwagger.PostSavingsProductsRequest.class)))
     @ApiResponses({
             @ApiResponse(responseCode = "200", description = "OK", content = 
@Content(schema = @Schema(implementation = 
SavingsProductsApiResourceSwagger.PostSavingsProductsResponse.class))) })
@@ -229,7 +232,8 @@ public class SavingsProductsApiResource {
     @Consumes({ MediaType.APPLICATION_JSON })
     @Produces({ MediaType.APPLICATION_JSON })
     @Operation(summary = "Retrieve Savings Product Template", description = 
"This is a convenience resource. It can be useful when building maintenance 
user interface screens for client applications. The template data returned 
consists of any or all of:\n"
-            + "\n" + "Field Defaults\n" + "Allowed description Lists\n" + 
"Example Request:\n" + "\n" + "savingsproducts/template")
+            + "\n" + "Field Defaults\n" + "Allowed description Lists\n" + 
"Example Request:\n" + "Account Mapping:\n" + "\n"
+            + "savingsproducts/template")
     @ApiResponses({
             @ApiResponse(responseCode = "200", description = "OK", content = 
@Content(schema = @Schema(implementation = 
SavingsProductsApiResourceSwagger.GetSavingsProductsTemplateResponse.class))) })
     public String retrieveTemplate(@Context final UriInfo uriInfo) {
@@ -288,6 +292,8 @@ public class SavingsProductsApiResource {
         final Map<String, List<GLAccountData>> accountingMappingOptions = 
this.accountingDropdownReadPlatformService
                 .retrieveAccountMappingOptionsForSavingsProducts();
 
+        final String accountMappingForPayment = 
configurationDomainService.getAccountMappingForPaymentType();
+
         // charges
         final boolean feeChargesOnly = false;
         Collection<ChargeData> chargeOptions = 
this.chargeReadPlatformService.retrieveSavingsProductApplicableCharges(feeChargesOnly);
@@ -301,13 +307,14 @@ public class SavingsProductsApiResource {
             savingsProductToReturn = 
SavingsProductData.withTemplate(savingsProduct, currencyOptions, 
interestCompoundingPeriodTypeOptions,
                     interestPostingPeriodTypeOptions, 
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
                     lockinPeriodFrequencyTypeOptions, 
withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions,
-                    accountingMappingOptions, chargeOptions, penaltyOptions, 
taxGroupOptions);
+                    accountingMappingOptions, chargeOptions, penaltyOptions, 
taxGroupOptions, accountMappingForPayment);
         } else {
             savingsProductToReturn = SavingsProductData.template(currency, 
interestCompoundingPeriodType, interestPostingPeriodType,
                     interestCalculationType, 
interestCalculationDaysInYearType, accountingRule, currencyOptions,
                     interestCompoundingPeriodTypeOptions, 
interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
                     interestCalculationDaysInYearTypeOptions, 
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions,
-                    paymentTypeOptions, accountingRuleOptions, 
accountingMappingOptions, chargeOptions, penaltyOptions, taxGroupOptions);
+                    paymentTypeOptions, accountingRuleOptions, 
accountingMappingOptions, chargeOptions, penaltyOptions, taxGroupOptions,
+                    accountMappingForPayment);
         }
 
         return savingsProductToReturn;
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsProductsApiResourceSwagger.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsProductsApiResourceSwagger.java
index 20fdd3e..5aaeabb 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsProductsApiResourceSwagger.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsProductsApiResourceSwagger.java
@@ -70,6 +70,8 @@ final class SavingsProductsApiResourceSwagger {
         @Schema(example = "1")
         public Integer accountingRule;
         public Set<PostSavingsCharges> charges;
+        @Schema(example = "accountMappingForPayment")
+        public String accountMappingForPayment;
     }
 
     @Schema(description = "PostSavingsProductsResponse")
@@ -725,6 +727,8 @@ final class SavingsProductsApiResourceSwagger {
         public Set<GetSavingsProductsTemplateAccountingRule> 
accountingRuleOptions;
         public GetSavingsProductsAccountingMappingOptions 
accountingMappingOptions;
         public Set<GetSavingsProductsChargeOptions> chargeOptions;
+        public GetSavingsProductsResponse.GetSavingsCurrency accountMapping;
+
     }
 
     @Schema(description = "DeleteSavingsProductsProductIdResponse")
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductData.java
index 856adf4..95505c8 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductData.java
@@ -62,6 +62,7 @@ public final class SavingsProductData implements Serializable 
{
     private final boolean withHoldTax;
     private final TaxGroupData taxGroup;
     private String depositAccountType = null;
+    private final String accountMappingForPayment;
 
     // accounting
     private final EnumOptionData accountingRule;
@@ -102,7 +103,8 @@ public final class SavingsProductData implements 
Serializable {
             final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, 
final Collection<EnumOptionData> withdrawalFeeTypeOptions,
             final Collection<PaymentTypeData> paymentTypeOptions, final 
Collection<EnumOptionData> accountingRuleOptions,
             final Map<String, List<GLAccountData>> accountingMappingOptions, 
final Collection<ChargeData> chargeOptions,
-            final Collection<ChargeData> penaltyOptions, final 
Collection<TaxGroupData> taxGroupOptions) {
+            final Collection<ChargeData> penaltyOptions, final 
Collection<TaxGroupData> taxGroupOptions,
+            final String accountMappingForPayment) {
 
         final Long id = null;
         final String name = null;
@@ -141,7 +143,7 @@ public final class SavingsProductData implements 
Serializable {
                 penaltyOptions, feeToIncomeAccountMappings, 
penaltyToIncomeAccountMappings, allowOverdraft, overdraftLimit,
                 minRequiredBalance, enforceMinRequiredBalance, 
minBalanceForInterestCalculation, nominalAnnualInterestRateOverdraft,
                 minOverdraftForInterestCalculation, withHoldTax, taxGroup, 
taxGroupOptions, isDormancyTrackingActive, daysToInactive,
-                daysToDormancy, daysToEscheat);
+                daysToDormancy, daysToEscheat, accountMappingForPayment);
     }
 
     public static SavingsProductData withCharges(final SavingsProductData 
product, final Collection<ChargeData> charges) {
@@ -158,7 +160,7 @@ public final class SavingsProductData implements 
Serializable {
                 product.minRequiredBalance, product.enforceMinRequiredBalance, 
product.minBalanceForInterestCalculation,
                 product.nominalAnnualInterestRateOverdraft, 
product.minOverdraftForInterestCalculation, product.withHoldTax,
                 product.taxGroup, product.taxGroupOptions, 
product.isDormancyTrackingActive, product.daysToInactive, 
product.daysToDormancy,
-                product.daysToEscheat);
+                product.daysToEscheat, product.accountMappingForPayment);
     }
 
     /**
@@ -167,6 +169,7 @@ public final class SavingsProductData implements 
Serializable {
      *
      * @param taxGroupOptions
      *            TODO
+     * @param accountMapping
      */
     public static SavingsProductData withTemplate(final SavingsProductData 
existingProduct, final Collection<CurrencyData> currencyOptions,
             final Collection<EnumOptionData> 
interestCompoundingPeriodTypeOptions,
@@ -176,7 +179,7 @@ public final class SavingsProductData implements 
Serializable {
             final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, 
final Collection<EnumOptionData> withdrawalFeeTypeOptions,
             final Collection<PaymentTypeData> paymentTypeOptions, final 
Collection<EnumOptionData> accountingRuleOptions,
             final Map<String, List<GLAccountData>> accountingMappingOptions, 
final Collection<ChargeData> chargeOptions,
-            final Collection<ChargeData> penaltyOptions, 
Collection<TaxGroupData> taxGroupOptions) {
+            final Collection<ChargeData> penaltyOptions, 
Collection<TaxGroupData> taxGroupOptions, final String 
accountMappingForPayment) {
 
         return new SavingsProductData(existingProduct.id, 
existingProduct.name, existingProduct.shortName, existingProduct.description,
                 existingProduct.currency, 
existingProduct.nominalAnnualInterestRate, 
existingProduct.interestCompoundingPeriodType,
@@ -192,7 +195,7 @@ public final class SavingsProductData implements 
Serializable {
                 existingProduct.minBalanceForInterestCalculation, 
existingProduct.nominalAnnualInterestRateOverdraft,
                 existingProduct.minOverdraftForInterestCalculation, 
existingProduct.withHoldTax, existingProduct.taxGroup, taxGroupOptions,
                 existingProduct.isDormancyTrackingActive, 
existingProduct.daysToInactive, existingProduct.daysToDormancy,
-                existingProduct.daysToEscheat);
+                existingProduct.daysToEscheat, 
existingProduct.accountMappingForPayment);
     }
 
     public static SavingsProductData withAccountingDetails(final 
SavingsProductData existingProduct,
@@ -212,6 +215,7 @@ public final class SavingsProductData implements 
Serializable {
         final Map<String, List<GLAccountData>> accountingMappingOptions = null;
         final Collection<ChargeData> chargeOptions = null;
         final Collection<ChargeData> penaltyOptions = null;
+        final String accountMappingForPayment = null;
 
         return new SavingsProductData(existingProduct.id, 
existingProduct.name, existingProduct.shortName, existingProduct.description,
                 existingProduct.currency, 
existingProduct.nominalAnnualInterestRate, 
existingProduct.interestCompoundingPeriodType,
@@ -227,7 +231,7 @@ public final class SavingsProductData implements 
Serializable {
                 existingProduct.minBalanceForInterestCalculation, 
existingProduct.nominalAnnualInterestRateOverdraft,
                 existingProduct.minOverdraftForInterestCalculation, 
existingProduct.withHoldTax, existingProduct.taxGroup,
                 existingProduct.taxGroupOptions, 
existingProduct.isDormancyTrackingActive, existingProduct.daysToInactive,
-                existingProduct.daysToDormancy, existingProduct.daysToEscheat);
+                existingProduct.daysToDormancy, existingProduct.daysToEscheat, 
existingProduct.accountMappingForPayment);
     }
 
     public static SavingsProductData instance(final Long id, final String 
name, final String shortName, final String description,
@@ -260,6 +264,7 @@ public final class SavingsProductData implements 
Serializable {
         final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = 
null;
         final Collection<ChargeToGLAccountMapper> 
penaltyToIncomeAccountMappings = null;
         final Collection<TaxGroupData> taxGroupOptions = null;
+        final String accountMappingForPayment = null;
 
         return new SavingsProductData(id, name, shortName, description, 
currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
                 interestPostingPeriodType, interestCalculationType, 
interestCalculationDaysInYearType, minRequiredOpeningBalance,
@@ -270,7 +275,7 @@ public final class SavingsProductData implements 
Serializable {
                 penaltyOptions, feeToIncomeAccountMappings, 
penaltyToIncomeAccountMappings, allowOverdraft, overdraftLimit,
                 minRequiredBalance, enforceMinRequiredBalance, 
minBalanceForInterestCalculation, nominalAnnualInterestRateOverdraft,
                 minOverdraftForInterestCalculation, withHoldTax, taxGroup, 
taxGroupOptions, isDormancyTrackingActive, daysToInactive,
-                daysToDormancy, daysToEscheat);
+                daysToDormancy, daysToEscheat, accountMappingForPayment);
     }
 
     public static SavingsProductData lookup(final Long id, final String name) {
@@ -320,6 +325,7 @@ public final class SavingsProductData implements 
Serializable {
         final Long daysToInactive = null;
         final Long daysToDormancy = null;
         final Long daysToEscheat = null;
+        final String accountMappingForPayment = null;
 
         return new SavingsProductData(id, name, shortName, description, 
currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
                 interestPostingPeriodType, interestCalculationType, 
interestCalculationDaysInYearType, minRequiredOpeningBalance,
@@ -330,7 +336,7 @@ public final class SavingsProductData implements 
Serializable {
                 penaltyOptions, feeToIncomeAccountMappings, 
penaltyToIncomeAccountMappings, allowOverdraft, overdraftLimit,
                 minRequiredBalance, enforceMinRequiredBalance, 
minBalanceForInterestCalculation, nominalAnnualInterestRateOverdraft,
                 minOverdraftForInterestCalculation, withHoldTax, taxGroup, 
taxGroupOptions, isDormancyTrackingActive, daysToInactive,
-                daysToDormancy, daysToEscheat);
+                daysToDormancy, daysToEscheat, accountMappingForPayment);
     }
 
     private SavingsProductData(final Long id, final String name, final String 
shortName, final String description,
@@ -354,7 +360,7 @@ public final class SavingsProductData implements 
Serializable {
             final BigDecimal minBalanceForInterestCalculation, final 
BigDecimal nominalAnnualInterestRateOverdraft,
             final BigDecimal minOverdraftForInterestCalculation, final boolean 
withHoldTax, final TaxGroupData taxGroup,
             final Collection<TaxGroupData> taxGroupOptions, final Boolean 
isDormancyTrackingActive, final Long daysToInactive,
-            final Long daysToDormancy, final Long daysToEscheat) {
+            final Long daysToDormancy, final Long daysToEscheat, final String 
accountMappingForPayment) {
         this.id = id;
         this.name = name;
         this.shortName = shortName;
@@ -411,6 +417,7 @@ public final class SavingsProductData implements 
Serializable {
         this.daysToInactive = daysToInactive;
         this.daysToDormancy = daysToDormancy;
         this.daysToEscheat = daysToEscheat;
+        this.accountMappingForPayment = accountMappingForPayment;
     }
 
     public boolean hasAccountingEnabled() {
diff --git 
a/fineract-provider/src/main/resources/sql/migrations/core_db/V374__adding_expenseliablity_to_paymentorfeetype.sql
 
b/fineract-provider/src/main/resources/sql/migrations/core_db/V374__adding_expenseliablity_to_paymentorfeetype.sql
new file mode 100644
index 0000000..42f8def
--- /dev/null
+++ 
b/fineract-provider/src/main/resources/sql/migrations/core_db/V374__adding_expenseliablity_to_paymentorfeetype.sql
@@ -0,0 +1,25 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements. See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership. The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"); you may not use this file except in compliance
+-- with the License. You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing,
+-- software distributed under the License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-- KIND, either express or implied. See the License for the
+-- specific language governing permissions and limitations
+-- under the License.'=.
+--
+
+ALTER TABLE `c_configuration`
+    ADD COLUMN `string_value` VARCHAR(100) NULL DEFAULT NULL AFTER 
`date_value`;
+
+insert into c_configuration(name, string_value, enabled, description) 
values('account-mapping-for-payment-type', 'Asset', '1', 'Asset: default for 
asset, Use comma seperated values for Liability, Asset and Expense accounts');
+
+insert into c_configuration(name, string_value, enabled, description) 
values('account-mapping-for-charge', 'Income', '1', 'Income: default for 
Income, Use comma seperated values for Income, Liability and Expense accounts');

Reply via email to