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');