update current product code and RD code
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
description = 'Fineract Current Product'
|
||||
|
||||
compileJava {
|
||||
dependsOn ':fineract-avro-schemas:buildJavaSdk'
|
||||
}
|
||||
|
||||
configurations {
|
||||
providedRuntime // needed for Spring Boot executable WAR
|
||||
providedCompile
|
||||
compile() {
|
||||
exclude module: 'hibernate-entitymanager'
|
||||
exclude module: 'hibernate-validator'
|
||||
exclude module: 'activation'
|
||||
exclude module: 'bcmail-jdk14'
|
||||
exclude module: 'bcprov-jdk14'
|
||||
exclude module: 'bctsp-jdk14'
|
||||
exclude module: 'c3p0'
|
||||
exclude module: 'stax-api'
|
||||
exclude module: 'jaxb-api'
|
||||
exclude module: 'jaxb-impl'
|
||||
exclude module: 'jboss-logging'
|
||||
exclude module: 'itext-rtf'
|
||||
exclude module: 'classworlds'
|
||||
}
|
||||
runtime
|
||||
}
|
||||
|
||||
apply from: 'dependencies.gradle'
|
||||
|
||||
// If we are running Gradle within Eclipse to enhance classes with OpenJPA,
|
||||
// set the classes directory to point to Eclipse's default build directory
|
||||
if (project.hasProperty('env') && project.getProperty('env') == 'eclipse') {
|
||||
sourceSets.main.java.outputDir = new File(rootProject.projectDir, "fineract-current-product/bin/main")
|
||||
}
|
||||
|
||||
eclipse {
|
||||
project {
|
||||
buildCommand([ LaunchConfigHandle: "<project>/.externalToolBuilders/OpenJPA Enhance Builder.launch" ], 'org.eclipse.ui.externaltools.ExternalToolBuilder')
|
||||
}
|
||||
}
|
||||
|
||||
if (!(project.hasProperty('env') && project.getProperty('env') == 'dev')) {
|
||||
sourceSets {
|
||||
test {
|
||||
java {
|
||||
exclude '**/core/boot/tests/**'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
dependencies {
|
||||
// Never use "compile" scope, but make all dependencies either 'implementation', 'runtimeOnly' or 'testCompile'.
|
||||
|
||||
implementation(project(path: ':fineract-core'))
|
||||
implementation(project(path: ':fineract-accounting'))
|
||||
implementation(project(path: ':fineract-charge'))
|
||||
implementation(project(path: ':fineract-tax'))
|
||||
implementation(project(path: ':fineract-savings'))
|
||||
|
||||
implementation(
|
||||
'org.springframework.boot:spring-boot-starter-web',
|
||||
'org.springframework.boot:spring-boot-starter-security',
|
||||
'jakarta.ws.rs:jakarta.ws.rs-api',
|
||||
|
||||
'com.google.guava:guava',
|
||||
'com.google.code.gson:gson',
|
||||
|
||||
'org.apache.commons:commons-lang3',
|
||||
|
||||
'com.jayway.jsonpath:json-path',
|
||||
|
||||
'com.github.spotbugs:spotbugs-annotations',
|
||||
'io.swagger.core.v3:swagger-annotations-jakarta',
|
||||
|
||||
'org.mapstruct:mapstruct',
|
||||
)
|
||||
compileOnly 'org.projectlombok:lombok'
|
||||
annotationProcessor 'org.projectlombok:lombok'
|
||||
annotationProcessor 'org.mapstruct:mapstruct-processor'
|
||||
implementation ('org.springframework.boot:spring-boot-starter-data-jpa') {
|
||||
exclude group: 'org.hibernate'
|
||||
}
|
||||
implementation('org.eclipse.persistence:org.eclipse.persistence.jpa') {
|
||||
exclude group: 'org.eclipse.persistence', module: 'jakarta.persistence'
|
||||
}
|
||||
testImplementation( 'io.github.classgraph:classgraph' )
|
||||
testImplementation ('org.springframework.boot:spring-boot-starter-test') {
|
||||
exclude group: 'com.jayway.jsonpath', module: 'json-path'
|
||||
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
|
||||
exclude group: 'jakarta.activation'
|
||||
exclude group: 'javax.activation'
|
||||
exclude group: 'org.skyscreamer'
|
||||
}
|
||||
testImplementation ('org.mockito:mockito-inline')
|
||||
}
|
||||
+460
@@ -0,0 +1,460 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.data;
|
||||
|
||||
import static org.apache.fineract.portfolio.savings.DepositsApiConstants.CURRENT_PRODUCT_RESOURCE_NAME;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.allowOverdraftParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.currencyCodeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToDormancyParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToEscheatParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToInactiveParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.descriptionParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.digitsAfterDecimalParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.feeAmountParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.feeOnMonthDayParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.inMultiplesOfParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCalculationTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestPostingPeriodTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.isDormancyTrackingActiveParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lienAllowedParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.maxAllowedLienLimitParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minBalanceForInterestCalculationParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minOverdraftForInterestCalculationParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nameParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateOverdraftParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.overdraftLimitParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.shortNameParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.taxGroupIdParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.MonthDay;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.SavingProductAccountingParams;
|
||||
import org.apache.fineract.accounting.common.AccountingValidations;
|
||||
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.portfolio.savings.DepositAccountType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsApiConstants;
|
||||
import org.apache.fineract.portfolio.savings.SavingsCompoundingInterestPeriodType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationDaysInYearType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProduct;
|
||||
import org.apache.fineract.portfolio.savings.data.SavingsProductAccountingDataValidator;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CurrentProductDataValidator {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
private final SavingsProductAccountingDataValidator savingsProductAccountingDataValidator;
|
||||
|
||||
private static final Set<String> CURRENT_PRODUCT_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(
|
||||
SavingsApiConstants.localeParamName, SavingsApiConstants.dateFormatParamName,
|
||||
SavingsApiConstants.monthDayFormatParamName, nameParamName, shortNameParamName,
|
||||
descriptionParamName, currencyCodeParamName, digitsAfterDecimalParamName, inMultiplesOfParamName,
|
||||
nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName,
|
||||
interestPostingPeriodTypeParamName, interestCalculationTypeParamName,
|
||||
interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName,
|
||||
lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName,
|
||||
SavingsApiConstants.withdrawalFeeAmountParamName, SavingsApiConstants.withdrawalFeeTypeParamName,
|
||||
withdrawalFeeForTransfersParamName, feeAmountParamName, feeOnMonthDayParamName,
|
||||
SavingsApiConstants.accountingRuleParamName, SavingsApiConstants.chargesParamName,
|
||||
SavingsApiConstants.otherGlMappingsParamName,
|
||||
SavingProductAccountingParams.INCOME_FROM_FEES.getValue(),
|
||||
SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(),
|
||||
SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(),
|
||||
SavingProductAccountingParams.PENALTIES_RECEIVABLE.getValue(),
|
||||
SavingProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
|
||||
SavingProductAccountingParams.SAVINGS_CONTROL.getValue(),
|
||||
SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(),
|
||||
SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(),
|
||||
SavingProductAccountingParams.FEE_INCOME_ACCOUNT_MAPPING.getValue(),
|
||||
SavingProductAccountingParams.PENALTY_INCOME_ACCOUNT_MAPPING.getValue(),
|
||||
SavingProductAccountingParams.FEES_RECEIVABLE.getValue(),
|
||||
SavingProductAccountingParams.INTEREST_PAYABLE.getValue(),
|
||||
SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
|
||||
SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(),
|
||||
SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue(),
|
||||
SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue(),
|
||||
SavingProductAccountingParams.INTEREST_RECEIVABLE.getValue(),
|
||||
isDormancyTrackingActiveParamName, daysToDormancyParamName, daysToInactiveParamName,
|
||||
daysToEscheatParamName, allowOverdraftParamName, overdraftLimitParamName,
|
||||
nominalAnnualInterestRateOverdraftParamName, minOverdraftForInterestCalculationParamName,
|
||||
SavingsApiConstants.minRequiredBalanceParamName, SavingsApiConstants.enforceMinRequiredBalanceParamName,
|
||||
SavingsApiConstants.maxAllowedLienLimitParamName, SavingsApiConstants.lienAllowedParamName,
|
||||
minBalanceForInterestCalculationParamName, withHoldTaxParamName, taxGroupIdParamName,
|
||||
SavingsApiConstants.accountTypeParamName, SavingsApiConstants.customerSegmentParamName,
|
||||
SavingsApiConstants.productCodeParamName, SavingsApiConstants.effectiveDateParamName,
|
||||
SavingsApiConstants.effectiveToParamName, SavingsApiConstants.endDateParamName,
|
||||
SavingsApiConstants.introducerRequiredParamName, SavingsApiConstants.shareLinkingEnabledParamName,
|
||||
SavingsApiConstants.nominationFacilityParamName, SavingsApiConstants.dormancyAlertParamName,
|
||||
SavingsApiConstants.interestCalculateSelectorParamName, SavingsApiConstants.averagePeriodParamName,
|
||||
SavingsApiConstants.autoPostParamName, SavingsApiConstants.frequencyFixDayParamName,
|
||||
SavingsApiConstants.lastInterestDateParamName, SavingsApiConstants.enableLockinPeriodParamName,
|
||||
SavingsApiConstants.accountFacilityConfigParamName, SavingsApiConstants.accountFacilityLimitsParamName,
|
||||
SavingsApiConstants.depositLimitKycParamName,
|
||||
SavingsApiConstants.balanceFrequencyParamName, SavingsApiConstants.accountClosedZeroBalanceInDayClosingParamName,
|
||||
SavingsApiConstants.balanceSwapOptionParamName, SavingsApiConstants.msmeParamName,
|
||||
SavingsApiConstants.autoDebitFacilityParamName, SavingsApiConstants.avgBalanceCalcPeriodParamName,
|
||||
SavingsApiConstants.validForPeriodParamName, SavingsApiConstants.odAccountClosedZeroBalanceInDayClosingParamName));
|
||||
|
||||
public void validateForCreate(final String json) {
|
||||
if (StringUtils.isBlank(json)) {
|
||||
throw new InvalidJsonException();
|
||||
}
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, CURRENT_PRODUCT_REQUEST_DATA_PARAMETERS);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(CURRENT_PRODUCT_RESOURCE_NAME);
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
final String name = this.fromApiJsonHelper.extractStringNamed(nameParamName, element);
|
||||
baseDataValidator.reset().parameter(nameParamName).value(name).notBlank().notExceedingLengthOf(100);
|
||||
|
||||
final String shortName = this.fromApiJsonHelper.extractStringNamed(shortNameParamName, element);
|
||||
baseDataValidator.reset().parameter(shortNameParamName).value(shortName).notBlank().notExceedingLengthOf(4);
|
||||
|
||||
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(currencyCodeParamName, element);
|
||||
baseDataValidator.reset().parameter(currencyCodeParamName).value(currencyCode).notBlank();
|
||||
|
||||
final Integer digitsAfterDecimal = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(digitsAfterDecimalParamName, element);
|
||||
baseDataValidator.reset().parameter(digitsAfterDecimalParamName).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(inMultiplesOfParamName, element)) {
|
||||
final Integer inMultiplesOf = this.fromApiJsonHelper.extractIntegerNamed(inMultiplesOfParamName, element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter(inMultiplesOfParamName).value(inMultiplesOf).ignoreIfNull().integerZeroOrGreater();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(nominalAnnualInterestRateParamName, element)) {
|
||||
final BigDecimal nominalAnnualInterestRate = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(nominalAnnualInterestRate).zeroOrPositiveAmount();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
|
||||
final Integer interestCompoundingPeriodType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCompoundingPeriodTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType)
|
||||
.isOneOfTheseValues(SavingsCompoundingInterestPeriodType.integerValues());
|
||||
}
|
||||
|
||||
final Integer interestPostingPeriodType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestPostingPeriodTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestPostingPeriodTypeParamName).value(interestPostingPeriodType).notNull()
|
||||
.isOneOfTheseValues(SavingsPostingInterestPeriodType.integerValues());
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) {
|
||||
final Integer interestCalculationType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(interestCalculationDaysInYearTypeParamName, element)) {
|
||||
final Integer interestCalculationDaysInYearType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationDaysInYearTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType)
|
||||
.isOneOfTheseValues(SavingsInterestCalculationDaysInYearType.integerValues());
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(descriptionParamName, element)) {
|
||||
final String description = this.fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
|
||||
baseDataValidator.reset().parameter(descriptionParamName).value(description).ignoreIfNull().notExceedingLengthOf(500);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
|
||||
final BigDecimal minOpeningBalance = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName, element);
|
||||
baseDataValidator.reset().parameter(minRequiredOpeningBalanceParamName).value(minOpeningBalance).zeroOrPositiveAmount();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
|
||||
final Integer lockinPeriodFrequency = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName, element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).integerZeroOrGreater();
|
||||
if (lockinPeriodFrequency != null) {
|
||||
final Integer lockinPeriodFrequencyType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).notNull().inMinMaxRange(0, 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
|
||||
final Integer lockinPeriodFrequencyType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(0, 3);
|
||||
if (lockinPeriodFrequencyType != null) {
|
||||
final Integer lockinPeriodFrequency = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName, element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).notNull().integerZeroOrGreater();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(withdrawalFeeForTransfersParamName, element)) {
|
||||
final Boolean isWithdrawalFeeApplicableForTransfers = this.fromApiJsonHelper.extractBooleanNamed(withdrawalFeeForTransfersParamName, element);
|
||||
baseDataValidator.reset().parameter(withdrawalFeeForTransfersParamName).value(isWithdrawalFeeApplicableForTransfers).ignoreIfNull().validateForBooleanValue();
|
||||
}
|
||||
|
||||
// dormancy
|
||||
Boolean isDormancyActive = this.fromApiJsonHelper.extractBooleanNamed(isDormancyTrackingActiveParamName, element);
|
||||
if (isDormancyActive == null) {
|
||||
isDormancyActive = false;
|
||||
}
|
||||
if (isDormancyActive) {
|
||||
final Long daysToInact = this.fromApiJsonHelper.extractLongNamed(daysToInactiveParamName, element);
|
||||
baseDataValidator.reset().parameter(daysToInactiveParamName).value(daysToInact).notNull().longGreaterThanZero();
|
||||
final Long daysToDor = this.fromApiJsonHelper.extractLongNamed(daysToDormancyParamName, element);
|
||||
baseDataValidator.reset().parameter(daysToDormancyParamName).value(daysToDor).notNull().longGreaterThanZero();
|
||||
final Long daysToEsc = this.fromApiJsonHelper.extractLongNamed(daysToEscheatParamName, element);
|
||||
baseDataValidator.reset().parameter(daysToEscheatParamName).value(daysToEsc).notNull().longGreaterThanZero();
|
||||
if (null != daysToInact && null != daysToDor && null != daysToEsc) {
|
||||
baseDataValidator.reset().parameter(daysToDormancyParamName).value(daysToDor).longGreaterThanNumber(daysToInact);
|
||||
baseDataValidator.reset().parameter(daysToEscheatParamName).value(daysToEsc).longGreaterThanNumber(daysToDor);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(SavingsApiConstants.effectiveToParamName, element)
|
||||
&& this.fromApiJsonHelper.parameterExists(SavingsApiConstants.effectiveDateParamName, element)) {
|
||||
final java.time.LocalDate effectiveDate = this.fromApiJsonHelper.extractLocalDateNamed(SavingsApiConstants.effectiveDateParamName, element);
|
||||
final java.time.LocalDate effectiveTo = this.fromApiJsonHelper.extractLocalDateNamed(SavingsApiConstants.effectiveToParamName, element);
|
||||
if (effectiveDate != null && effectiveTo != null && effectiveTo.isBefore(effectiveDate)) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.effectiveToParamName).value(effectiveTo)
|
||||
.failWithCode("error.msg.effectiveto.cannot.be.before.effectivedate");
|
||||
}
|
||||
}
|
||||
|
||||
final Integer accountingRuleType = this.fromApiJsonHelper.extractIntegerNamed("accountingRule", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("accountingRule").value(accountingRuleType).notNull().inMinMaxRange(1, 3);
|
||||
|
||||
if (AccountingValidations.isCashBasedAccounting(accountingRuleType)
|
||||
|| AccountingValidations.isAccrualPeriodicBasedAccounting(accountingRuleType)) {
|
||||
savingsProductAccountingDataValidator.evaluateProductAccountingData(accountingRuleType, isDormancyActive, element,
|
||||
baseDataValidator, DepositAccountType.SAVINGS_DEPOSIT, true);
|
||||
}
|
||||
|
||||
validateOverdraftParams(baseDataValidator, element);
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(minBalanceForInterestCalculationParamName, element)) {
|
||||
final BigDecimal minBalanceForInterestCalculation = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minBalanceForInterestCalculationParamName, element);
|
||||
baseDataValidator.reset().parameter(minBalanceForInterestCalculationParamName).value(minBalanceForInterestCalculation).ignoreIfNull().zeroOrPositiveAmount();
|
||||
}
|
||||
|
||||
validateTaxWithHoldingParams(baseDataValidator, element, true);
|
||||
validateLienParams(baseDataValidator, element);
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForUpdate(final String json, final CurrentProduct product) {
|
||||
if (StringUtils.isBlank(json)) {
|
||||
throw new InvalidJsonException();
|
||||
}
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, CURRENT_PRODUCT_REQUEST_DATA_PARAMETERS);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(CURRENT_PRODUCT_RESOURCE_NAME);
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(nameParamName, element)) {
|
||||
final String name = this.fromApiJsonHelper.extractStringNamed(nameParamName, element);
|
||||
baseDataValidator.reset().parameter(nameParamName).value(name).notBlank().notExceedingLengthOf(100);
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(shortNameParamName, element)) {
|
||||
final String shortName = this.fromApiJsonHelper.extractStringNamed(shortNameParamName, element);
|
||||
baseDataValidator.reset().parameter(shortNameParamName).value(shortName).notBlank().notExceedingLengthOf(4);
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(descriptionParamName, element)) {
|
||||
final String description = this.fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
|
||||
baseDataValidator.reset().parameter(descriptionParamName).value(description).notBlank().notExceedingLengthOf(500);
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(currencyCodeParamName, element)) {
|
||||
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(currencyCodeParamName, element);
|
||||
baseDataValidator.reset().parameter(currencyCodeParamName).value(currencyCode).notBlank();
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(digitsAfterDecimalParamName, element)) {
|
||||
final Integer digitsAfterDecimal = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(digitsAfterDecimalParamName, element);
|
||||
baseDataValidator.reset().parameter(digitsAfterDecimalParamName).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(inMultiplesOfParamName, element)) {
|
||||
final Integer inMultiplesOf = this.fromApiJsonHelper.extractIntegerNamed(inMultiplesOfParamName, element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter(inMultiplesOfParamName).value(inMultiplesOf).ignoreIfNull().integerZeroOrGreater();
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(nominalAnnualInterestRateParamName, element)) {
|
||||
final BigDecimal interestRate = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
|
||||
final Integer interestCompoundingPeriodType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCompoundingPeriodTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
|
||||
.isOneOfTheseValues(SavingsCompoundingInterestPeriodType.integerValues());
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) {
|
||||
final Integer interestCalculationType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull().inMinMaxRange(1, 2);
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(interestCalculationDaysInYearTypeParamName, element)) {
|
||||
final Integer interestCalculationDaysInYearType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationDaysInYearTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType).notNull().isOneOfTheseValues(360, 365);
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
|
||||
final BigDecimal minOpeningBalance = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName, element);
|
||||
baseDataValidator.reset().parameter(minRequiredOpeningBalanceParamName).value(minOpeningBalance).ignoreIfNull().zeroOrPositiveAmount();
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
|
||||
final Integer lockinPeriodFrequency = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName, element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).ignoreIfNull().integerZeroOrGreater();
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
|
||||
final Integer lockinPeriodFrequencyType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(0, 3);
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(withdrawalFeeForTransfersParamName, element)) {
|
||||
final Boolean isWithdrawalFeeApplicableForTransfers = this.fromApiJsonHelper.extractBooleanNamed(withdrawalFeeForTransfersParamName, element);
|
||||
baseDataValidator.reset().parameter(withdrawalFeeForTransfersParamName).value(isWithdrawalFeeApplicableForTransfers).ignoreIfNull().validateForBooleanValue();
|
||||
}
|
||||
|
||||
Integer accountingRuleType = product.getAccountingType();
|
||||
if (this.fromApiJsonHelper.parameterExists("accountingRule", element)) {
|
||||
accountingRuleType = this.fromApiJsonHelper.extractIntegerNamed("accountingRule", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("accountingRule").value(accountingRuleType).notNull().inMinMaxRange(1, 3);
|
||||
}
|
||||
|
||||
final Boolean isDormancyActive = this.fromApiJsonHelper.parameterExists(isDormancyTrackingActiveParamName, element)
|
||||
? this.fromApiJsonHelper.extractBooleanNamed(isDormancyTrackingActiveParamName, element)
|
||||
: product.isDormancyTrackingActive();
|
||||
|
||||
if (AccountingValidations.isCashBasedAccounting(accountingRuleType)
|
||||
|| AccountingValidations.isAccrualPeriodicBasedAccounting(accountingRuleType)) {
|
||||
savingsProductAccountingDataValidator.evaluateProductAccountingData(accountingRuleType, isDormancyActive, element,
|
||||
baseDataValidator, DepositAccountType.SAVINGS_DEPOSIT, false);
|
||||
}
|
||||
|
||||
if (null != isDormancyActive && isDormancyActive) {
|
||||
final Long daysToInact = this.fromApiJsonHelper.parameterExists(daysToInactiveParamName, element)
|
||||
? this.fromApiJsonHelper.extractLongNamed(daysToInactiveParamName, element)
|
||||
: product.getDaysToInactive();
|
||||
baseDataValidator.reset().parameter(daysToInactiveParamName).value(daysToInact).notNull().longGreaterThanZero();
|
||||
final Long daysToDor = this.fromApiJsonHelper.parameterExists(daysToDormancyParamName, element)
|
||||
? this.fromApiJsonHelper.extractLongNamed(daysToDormancyParamName, element)
|
||||
: product.getDaysToDormancy();
|
||||
baseDataValidator.reset().parameter(daysToDormancyParamName).value(daysToDor).notNull().longGreaterThanZero();
|
||||
final Long daysToEsc = this.fromApiJsonHelper.parameterExists(daysToEscheatParamName, element)
|
||||
? this.fromApiJsonHelper.extractLongNamed(daysToEscheatParamName, element)
|
||||
: product.getDaysToEscheat();
|
||||
baseDataValidator.reset().parameter(daysToEscheatParamName).value(daysToEsc).notNull().longGreaterThanZero();
|
||||
if (null != daysToInact && null != daysToDor && null != daysToEsc) {
|
||||
baseDataValidator.reset().parameter(daysToDormancyParamName).value(daysToDor).longGreaterThanNumber(daysToInact);
|
||||
baseDataValidator.reset().parameter(daysToEscheatParamName).value(daysToEsc).longGreaterThanNumber(daysToDor);
|
||||
}
|
||||
}
|
||||
|
||||
validateOverdraftParams(baseDataValidator, element);
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(minBalanceForInterestCalculationParamName, element)) {
|
||||
final BigDecimal minBalanceForInterestCalculation = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minBalanceForInterestCalculationParamName, element);
|
||||
baseDataValidator.reset().parameter(minBalanceForInterestCalculationParamName).value(minBalanceForInterestCalculation).ignoreIfNull().zeroOrPositiveAmount();
|
||||
}
|
||||
|
||||
validateTaxWithHoldingParams(baseDataValidator, element, false);
|
||||
validateLienParams(baseDataValidator, element);
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateOverdraftParams(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
|
||||
if (this.fromApiJsonHelper.parameterExists(allowOverdraftParamName, element)) {
|
||||
final Boolean allowOverdraft = this.fromApiJsonHelper.extractBooleanNamed(allowOverdraftParamName, element);
|
||||
baseDataValidator.reset().parameter(allowOverdraftParamName).value(allowOverdraft).ignoreIfNull().validateForBooleanValue();
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(overdraftLimitParamName, element)) {
|
||||
final BigDecimal overdraftLimit = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(overdraftLimitParamName, element);
|
||||
baseDataValidator.reset().parameter(overdraftLimitParamName).value(overdraftLimit).ignoreIfNull().zeroOrPositiveAmount();
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(nominalAnnualInterestRateOverdraftParamName, element)) {
|
||||
final BigDecimal nominalAnnualInterestRateOverdraft = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateOverdraftParamName, element);
|
||||
baseDataValidator.reset().parameter(nominalAnnualInterestRateOverdraftParamName).value(nominalAnnualInterestRateOverdraft).ignoreIfNull().zeroOrPositiveAmount();
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(minOverdraftForInterestCalculationParamName, element)) {
|
||||
final BigDecimal minOverdraftForInterestCalculation = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minOverdraftForInterestCalculationParamName, element);
|
||||
baseDataValidator.reset().parameter(minOverdraftForInterestCalculationParamName).value(minOverdraftForInterestCalculation).ignoreIfNull().zeroOrPositiveAmount();
|
||||
}
|
||||
}
|
||||
|
||||
private void validateLienParams(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
|
||||
if (this.fromApiJsonHelper.parameterExists(lienAllowedParamName, element)) {
|
||||
final Boolean lienAllowed = this.fromApiJsonHelper.extractBooleanNamed(lienAllowedParamName, element);
|
||||
baseDataValidator.reset().parameter(lienAllowedParamName).value(lienAllowed).ignoreIfNull().validateForBooleanValue();
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(maxAllowedLienLimitParamName, element)) {
|
||||
final BigDecimal maxAllowedLienLimit = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(maxAllowedLienLimitParamName, element);
|
||||
baseDataValidator.reset().parameter(maxAllowedLienLimitParamName).value(maxAllowedLienLimit).ignoreIfNull().zeroOrPositiveAmount();
|
||||
}
|
||||
if (BooleanUtils.isTrue(this.fromApiJsonHelper.extractBooleanNamed(lienAllowedParamName, element))
|
||||
&& BooleanUtils.isTrue(this.fromApiJsonHelper.extractBooleanNamed(allowOverdraftParamName, element))) {
|
||||
final BigDecimal maxAllowedLienLimit = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(maxAllowedLienLimitParamName, element);
|
||||
final BigDecimal overdraftLimit = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(overdraftLimitParamName, element);
|
||||
if (overdraftLimit.compareTo(maxAllowedLienLimit) > 0) {
|
||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("Overdraft.limit.can.not.be.greater.than.lien.limit");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateTaxWithHoldingParams(final DataValidatorBuilder baseDataValidator, final JsonElement element, final boolean isCreate) {
|
||||
if (this.fromApiJsonHelper.parameterExists(withHoldTaxParamName, element)) {
|
||||
final String withHoldTax = this.fromApiJsonHelper.extractStringNamed(withHoldTaxParamName, element);
|
||||
baseDataValidator.reset().parameter(withHoldTaxParamName).value(withHoldTax).ignoreIfNull().validateForBooleanValue();
|
||||
}
|
||||
Boolean withHoldTax = this.fromApiJsonHelper.extractBooleanNamed(withHoldTaxParamName, element);
|
||||
if (withHoldTax == null) {
|
||||
withHoldTax = false;
|
||||
}
|
||||
if (this.fromApiJsonHelper.parameterExists(taxGroupIdParamName, element)) {
|
||||
final Long taxGroupId = this.fromApiJsonHelper.extractLongNamed(taxGroupIdParamName, element);
|
||||
baseDataValidator.reset().parameter(taxGroupIdParamName).value(taxGroupId).ignoreIfNull().longGreaterThanZero();
|
||||
if (withHoldTax) {
|
||||
baseDataValidator.reset().parameter(taxGroupIdParamName).value(taxGroupId).notBlank();
|
||||
}
|
||||
} else if (withHoldTax && isCreate) {
|
||||
final Long taxGroupId = null;
|
||||
baseDataValidator.reset().parameter(taxGroupIdParamName).value(taxGroupId).notBlank();
|
||||
}
|
||||
}
|
||||
}
|
||||
+868
@@ -0,0 +1,868 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.domain;
|
||||
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accountingRuleParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.allowOverdraftParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.chargesParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.currencyCodeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToDormancyParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToEscheatParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToInactiveParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.descriptionParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.digitsAfterDecimalParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.enforceMinRequiredBalanceParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.inMultiplesOfParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCalculationTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestPostingPeriodTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.isDormancyTrackingActiveParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lienAllowedParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.localeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.maxAllowedLienLimitParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minBalanceForInterestCalculationParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minOverdraftForInterestCalculationParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minRequiredBalanceParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nameParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateOverdraftParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.otherGlMappingsParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.overdraftLimitParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.shortNameParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.taxGroupIdParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accountTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.customerSegmentParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.productCodeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.effectiveDateParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.effectiveToParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.endDateParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.introducerRequiredParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.shareLinkingEnabledParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominationFacilityParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.dormancyAlertParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCalculateSelectorParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.averagePeriodParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.autoPostParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.frequencyFixDayParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lastInterestDateParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.enableLockinPeriodParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.balanceSwapOptionParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.msmeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.autoDebitFacilityParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.avgBalanceCalcPeriodParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.validForPeriodParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.odAccountClosedZeroBalanceInDayClosingParamName;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Embedded;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.Lob;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.UniqueConstraint;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.fineract.accounting.common.AccountingRuleType;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.charge.domain.Charge;
|
||||
import org.apache.fineract.portfolio.savings.SavingsCompoundingInterestPeriodType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationDaysInYearType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsPeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType;
|
||||
import org.apache.fineract.portfolio.tax.domain.TaxGroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_current_product", uniqueConstraints = {
|
||||
@UniqueConstraint(columnNames = { "name" }, name = "cp_unq_name"),
|
||||
@UniqueConstraint(columnNames = { "short_name" }, name = "cp_unq_short_name") })
|
||||
public class CurrentProduct extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@Column(name = "name", nullable = false, unique = true)
|
||||
private String name;
|
||||
|
||||
@Column(name = "short_name", nullable = false, unique = true)
|
||||
private String shortName;
|
||||
|
||||
@Column(name = "description", length = 500, nullable = false)
|
||||
private String description;
|
||||
|
||||
@Embedded
|
||||
private MonetaryCurrency currency;
|
||||
|
||||
@Column(name = "nominal_annual_interest_rate", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal nominalAnnualInterestRate;
|
||||
|
||||
@Column(name = "interest_compounding_period_enum", nullable = false)
|
||||
private Integer interestCompoundingPeriodType;
|
||||
|
||||
@Column(name = "interest_posting_period_enum", nullable = false)
|
||||
private Integer interestPostingPeriodType;
|
||||
|
||||
@Column(name = "interest_calculation_type_enum", nullable = false)
|
||||
private Integer interestCalculationType;
|
||||
|
||||
@Column(name = "interest_calculation_days_in_year_type_enum", nullable = false)
|
||||
private Integer interestCalculationDaysInYearType;
|
||||
|
||||
@Column(name = "min_required_opening_balance", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal minRequiredOpeningBalance;
|
||||
|
||||
@Column(name = "lockin_period_frequency", nullable = true)
|
||||
private Integer lockinPeriodFrequency;
|
||||
|
||||
@Column(name = "lockin_period_frequency_enum", nullable = true)
|
||||
private Integer lockinPeriodFrequencyType;
|
||||
|
||||
@Column(name = "accounting_type", nullable = false)
|
||||
private Integer accountingRule;
|
||||
|
||||
@Column(name = "withdrawal_fee_for_transfer")
|
||||
private boolean withdrawalFeeApplicableForTransfer;
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(name = "m_current_product_charge",
|
||||
joinColumns = @JoinColumn(name = "current_product_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "charge_id"))
|
||||
private Set<Charge> charges;
|
||||
|
||||
@Column(name = "allow_overdraft")
|
||||
private boolean allowOverdraft;
|
||||
|
||||
@Column(name = "overdraft_limit", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal overdraftLimit;
|
||||
|
||||
@Column(name = "nominal_annual_interest_rate_overdraft", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal nominalAnnualInterestRateOverdraft;
|
||||
|
||||
@Column(name = "min_overdraft_for_interest_calculation", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal minOverdraftForInterestCalculation;
|
||||
|
||||
@Column(name = "enforce_min_required_balance")
|
||||
private boolean enforceMinRequiredBalance;
|
||||
|
||||
@Column(name = "min_required_balance", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal minRequiredBalance;
|
||||
|
||||
@Column(name = "is_lien_allowed", nullable = false)
|
||||
private boolean lienAllowed;
|
||||
|
||||
@Column(name = "max_allowed_lien_limit", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal maxAllowedLienLimit;
|
||||
|
||||
@Column(name = "min_balance_for_interest_calculation", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal minBalanceForInterestCalculation;
|
||||
|
||||
@Column(name = "withhold_tax", nullable = false)
|
||||
private boolean withHoldTax;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "tax_group_id")
|
||||
private TaxGroup taxGroup;
|
||||
|
||||
@Column(name = "is_dormancy_tracking_active")
|
||||
private Boolean isDormancyTrackingActive;
|
||||
|
||||
@Column(name = "days_to_inactive")
|
||||
private Long daysToInactive;
|
||||
|
||||
@Column(name = "days_to_dormancy")
|
||||
private Long daysToDormancy;
|
||||
|
||||
@Column(name = "days_to_escheat")
|
||||
private Long daysToEscheat;
|
||||
|
||||
@Lob
|
||||
@Column(name = "other_gl_mappings")
|
||||
private String otherGlMappings;
|
||||
|
||||
// Enhanced fields
|
||||
@Column(name = "account_type", length = 50)
|
||||
private String accountType;
|
||||
|
||||
@Column(name = "customer_segment", length = 50)
|
||||
private String customerSegment;
|
||||
|
||||
@Column(name = "product_code", length = 20, unique = true)
|
||||
private String productCode;
|
||||
|
||||
@Column(name = "effective_date")
|
||||
private LocalDate effectiveDate;
|
||||
|
||||
@Column(name = "effective_to")
|
||||
private LocalDate effectiveTo;
|
||||
|
||||
@Column(name = "end_date")
|
||||
private LocalDate endDate;
|
||||
|
||||
@Column(name = "introducer_required")
|
||||
private boolean introducerRequired = false;
|
||||
|
||||
@Column(name = "share_linking_enabled")
|
||||
private boolean shareLinkingEnabled = false;
|
||||
|
||||
@Column(name = "nomination_facility")
|
||||
private boolean nominationFacility = false;
|
||||
|
||||
@Column(name = "dormancy_alert")
|
||||
private boolean dormancyAlert = false;
|
||||
|
||||
@Column(name = "interest_calculate_selector")
|
||||
private Integer interestCalculateSelector;
|
||||
|
||||
@Column(name = "average_period", length = 20)
|
||||
private String averagePeriod;
|
||||
|
||||
@Column(name = "auto_post")
|
||||
private boolean autoPost = false;
|
||||
|
||||
@Column(name = "frequency_fix_day")
|
||||
private Integer frequencyFixDay;
|
||||
|
||||
@Column(name = "last_interest_date")
|
||||
private LocalDate lastInterestDate;
|
||||
|
||||
@Column(name = "enable_lockin_period")
|
||||
private boolean enableLockinPeriod = false;
|
||||
|
||||
@Column(name = "balance_frequency", length = 50)
|
||||
private String balanceFrequency;
|
||||
|
||||
@Column(name = "account_closed_zero_balance_in_day_closing")
|
||||
private Boolean accountClosedZeroBalanceInDayClosing = false;
|
||||
|
||||
// New UI fields (Currency step)
|
||||
@Column(name = "balance_swap_option")
|
||||
private boolean balanceSwapOption = false;
|
||||
|
||||
@Column(name = "msme")
|
||||
private boolean msme = false;
|
||||
|
||||
@Column(name = "auto_debit_facility")
|
||||
private boolean autoDebitFacility = false;
|
||||
|
||||
// New UI fields (OD section)
|
||||
@Column(name = "avg_balance_calc_period", length = 10)
|
||||
private String avgBalanceCalcPeriod;
|
||||
|
||||
@Column(name = "valid_for_period", length = 10)
|
||||
private String validForPeriod;
|
||||
|
||||
@Column(name = "od_account_closed_zero_balance_in_day_closing")
|
||||
private boolean odAccountClosedZeroBalanceInDayClosing = false;
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL, mappedBy = "currentProduct", orphanRemoval = true)
|
||||
private CurrentProductFacilityConfig facilityConfig;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "currentProduct", orphanRemoval = true)
|
||||
private Set<CurrentProductFacilityLimit> facilityLimits = new HashSet<>();
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL, mappedBy = "currentProduct", orphanRemoval = true)
|
||||
private CurrentProductDepositLimitKyc depositLimitKyc;
|
||||
|
||||
public static CurrentProduct createNew(final String name, final String shortName, final String description,
|
||||
final MonetaryCurrency currency, final BigDecimal interestRate,
|
||||
final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
|
||||
final SavingsPostingInterestPeriodType interestPostingPeriodType,
|
||||
final SavingsInterestCalculationType interestCalculationType,
|
||||
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
|
||||
final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
|
||||
final boolean withdrawalFeeApplicableForTransfer, final AccountingRuleType accountingRuleType,
|
||||
final Set<Charge> charges, final boolean allowOverdraft, final BigDecimal overdraftLimit,
|
||||
final boolean enforceMinRequiredBalance, final BigDecimal minRequiredBalance,
|
||||
final boolean lienAllowed, final BigDecimal maxAllowedLienLimit,
|
||||
final BigDecimal minBalanceForInterestCalculation, final BigDecimal nominalAnnualInterestRateOverdraft,
|
||||
final BigDecimal minOverdraftForInterestCalculation, final boolean withHoldTax, final TaxGroup taxGroup,
|
||||
final String otherGlMappings, final Boolean isDormancyTrackingActive, final Long daysToInactive,
|
||||
final Long daysToDormancy, final Long daysToEscheat) {
|
||||
|
||||
return new CurrentProduct(name, shortName, description, currency, interestRate, interestCompoundingPeriodType,
|
||||
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
|
||||
minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
|
||||
withdrawalFeeApplicableForTransfer, accountingRuleType, charges, allowOverdraft, overdraftLimit,
|
||||
enforceMinRequiredBalance, minRequiredBalance, lienAllowed, maxAllowedLienLimit,
|
||||
minBalanceForInterestCalculation, nominalAnnualInterestRateOverdraft, minOverdraftForInterestCalculation,
|
||||
withHoldTax, taxGroup, otherGlMappings, isDormancyTrackingActive, daysToInactive, daysToDormancy,
|
||||
daysToEscheat);
|
||||
}
|
||||
|
||||
protected CurrentProduct() {
|
||||
this.name = null;
|
||||
this.description = null;
|
||||
}
|
||||
|
||||
private CurrentProduct(final String name, final String shortName, final String description,
|
||||
final MonetaryCurrency currency, final BigDecimal interestRate,
|
||||
final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
|
||||
final SavingsPostingInterestPeriodType interestPostingPeriodType,
|
||||
final SavingsInterestCalculationType interestCalculationType,
|
||||
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
|
||||
final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
|
||||
final boolean withdrawalFeeApplicableForTransfer, final AccountingRuleType accountingRuleType,
|
||||
final Set<Charge> charges, final boolean allowOverdraft, final BigDecimal overdraftLimit,
|
||||
final boolean enforceMinRequiredBalance, final BigDecimal minRequiredBalance,
|
||||
final boolean lienAllowed, final BigDecimal maxAllowedLienLimit,
|
||||
final BigDecimal minBalanceForInterestCalculation, final BigDecimal nominalAnnualInterestRateOverdraft,
|
||||
final BigDecimal minOverdraftForInterestCalculation, final boolean withHoldTax, final TaxGroup taxGroup,
|
||||
final String otherGlMappings, final Boolean isDormancyTrackingActive, final Long daysToInactive,
|
||||
final Long daysToDormancy, final Long daysToEscheat) {
|
||||
|
||||
this.name = name;
|
||||
this.shortName = shortName;
|
||||
this.description = description;
|
||||
this.currency = currency;
|
||||
this.nominalAnnualInterestRate = interestRate;
|
||||
this.interestCompoundingPeriodType = interestCompoundingPeriodType.getValue();
|
||||
this.interestPostingPeriodType = interestPostingPeriodType.getValue();
|
||||
this.interestCalculationType = interestCalculationType.getValue();
|
||||
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType.getValue();
|
||||
|
||||
if (minRequiredOpeningBalance != null) {
|
||||
this.minRequiredOpeningBalance = Money.of(currency, minRequiredOpeningBalance).getAmount();
|
||||
}
|
||||
|
||||
this.lockinPeriodFrequency = lockinPeriodFrequency;
|
||||
if (lockinPeriodFrequency != null && lockinPeriodFrequencyType != null) {
|
||||
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType.getValue();
|
||||
}
|
||||
|
||||
this.withdrawalFeeApplicableForTransfer = withdrawalFeeApplicableForTransfer;
|
||||
|
||||
if (accountingRuleType != null) {
|
||||
this.accountingRule = accountingRuleType.getValue();
|
||||
}
|
||||
|
||||
if (charges != null) {
|
||||
this.charges = charges;
|
||||
}
|
||||
|
||||
validateLockinDetails();
|
||||
|
||||
this.allowOverdraft = allowOverdraft;
|
||||
this.overdraftLimit = overdraftLimit;
|
||||
this.nominalAnnualInterestRateOverdraft = nominalAnnualInterestRateOverdraft;
|
||||
this.minOverdraftForInterestCalculation = minOverdraftForInterestCalculation;
|
||||
|
||||
ensureOverdraftLimitsSetForOverdraftAccounts();
|
||||
|
||||
this.enforceMinRequiredBalance = enforceMinRequiredBalance;
|
||||
this.minRequiredBalance = minRequiredBalance;
|
||||
this.lienAllowed = lienAllowed;
|
||||
this.maxAllowedLienLimit = maxAllowedLienLimit;
|
||||
this.minBalanceForInterestCalculation = minBalanceForInterestCalculation;
|
||||
this.withHoldTax = withHoldTax;
|
||||
this.taxGroup = taxGroup;
|
||||
this.otherGlMappings = otherGlMappings;
|
||||
|
||||
this.isDormancyTrackingActive = isDormancyTrackingActive == null ? Boolean.FALSE : isDormancyTrackingActive;
|
||||
this.daysToInactive = daysToInactive;
|
||||
this.daysToDormancy = daysToDormancy;
|
||||
this.daysToEscheat = daysToEscheat;
|
||||
}
|
||||
|
||||
private void ensureOverdraftLimitsSetForOverdraftAccounts() {
|
||||
if (this.allowOverdraft) {
|
||||
this.overdraftLimit = this.overdraftLimit == null ? BigDecimal.ZERO : this.overdraftLimit;
|
||||
this.nominalAnnualInterestRateOverdraft = this.nominalAnnualInterestRateOverdraft == null ? BigDecimal.ZERO
|
||||
: this.nominalAnnualInterestRateOverdraft;
|
||||
this.minOverdraftForInterestCalculation = this.minOverdraftForInterestCalculation == null ? BigDecimal.ZERO
|
||||
: this.minOverdraftForInterestCalculation;
|
||||
}
|
||||
}
|
||||
|
||||
private void validateLockinDetails() {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource("currentproduct");
|
||||
if (this.lockinPeriodFrequency == null) {
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(this.lockinPeriodFrequencyType)
|
||||
.ignoreIfNull().inMinMaxRange(0, 3);
|
||||
}
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
public MonetaryCurrency currency() {
|
||||
return this.currency.copy();
|
||||
}
|
||||
|
||||
public BigDecimal nominalAnnualInterestRate() {
|
||||
return this.nominalAnnualInterestRate;
|
||||
}
|
||||
|
||||
public Integer getAccountingType() {
|
||||
return this.accountingRule;
|
||||
}
|
||||
|
||||
public boolean withHoldTax() {
|
||||
return this.withHoldTax;
|
||||
}
|
||||
|
||||
public TaxGroup getTaxGroup() {
|
||||
return this.taxGroup;
|
||||
}
|
||||
|
||||
public void setTaxGroup(final TaxGroup taxGroup) {
|
||||
this.taxGroup = taxGroup;
|
||||
}
|
||||
|
||||
public CurrentProductFacilityConfig getFacilityConfig() {
|
||||
return this.facilityConfig;
|
||||
}
|
||||
|
||||
public void setFacilityConfig(CurrentProductFacilityConfig facilityConfig) {
|
||||
this.facilityConfig = facilityConfig;
|
||||
}
|
||||
|
||||
public Set<CurrentProductFacilityLimit> getFacilityLimits() {
|
||||
return this.facilityLimits;
|
||||
}
|
||||
|
||||
public void setFacilityLimits(Set<CurrentProductFacilityLimit> facilityLimits) {
|
||||
this.facilityLimits = facilityLimits;
|
||||
}
|
||||
|
||||
public CurrentProductDepositLimitKyc getDepositLimitKyc() {
|
||||
return this.depositLimitKyc;
|
||||
}
|
||||
|
||||
public void setDepositLimitKyc(CurrentProductDepositLimitKyc depositLimitKyc) {
|
||||
this.depositLimitKyc = depositLimitKyc;
|
||||
}
|
||||
|
||||
public boolean update(final Set<Charge> newCharges) {
|
||||
if (newCharges == null) {
|
||||
return false;
|
||||
}
|
||||
final Set<Charge> currentSetOfCharges = this.charges == null ? new HashSet<>() : this.charges;
|
||||
if (!currentSetOfCharges.equals(newCharges)) {
|
||||
this.charges = newCharges;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(10);
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
if (command.isChangeInStringParameterNamed(nameParamName, this.name)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(nameParamName);
|
||||
actualChanges.put(nameParamName, newValue);
|
||||
this.name = newValue;
|
||||
}
|
||||
if (command.isChangeInStringParameterNamed(shortNameParamName, this.shortName)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(shortNameParamName);
|
||||
actualChanges.put(shortNameParamName, newValue);
|
||||
this.shortName = newValue;
|
||||
}
|
||||
if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(descriptionParamName);
|
||||
actualChanges.put(descriptionParamName, newValue);
|
||||
this.description = newValue;
|
||||
}
|
||||
|
||||
Integer digitsAfterDecimal = this.currency.getDigitsAfterDecimal();
|
||||
if (command.isChangeInIntegerParameterNamed(digitsAfterDecimalParamName, digitsAfterDecimal)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(digitsAfterDecimalParamName);
|
||||
actualChanges.put(digitsAfterDecimalParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
digitsAfterDecimal = newValue;
|
||||
this.currency = new MonetaryCurrency(this.currency.getCode(), digitsAfterDecimal, this.currency.getInMultiplesOf());
|
||||
}
|
||||
|
||||
String currencyCode = this.currency.getCode();
|
||||
if (command.isChangeInStringParameterNamed(currencyCodeParamName, currencyCode)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(currencyCodeParamName);
|
||||
actualChanges.put(currencyCodeParamName, newValue);
|
||||
currencyCode = newValue;
|
||||
this.currency = new MonetaryCurrency(currencyCode, this.currency.getDigitsAfterDecimal(), this.currency.getInMultiplesOf());
|
||||
}
|
||||
|
||||
Integer inMultiplesOf = this.currency.getInMultiplesOf();
|
||||
if (command.isChangeInIntegerParameterNamed(inMultiplesOfParamName, inMultiplesOf)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(inMultiplesOfParamName);
|
||||
actualChanges.put(inMultiplesOfParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
inMultiplesOf = newValue;
|
||||
this.currency = new MonetaryCurrency(this.currency.getCode(), this.currency.getDigitsAfterDecimal(), inMultiplesOf);
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(nominalAnnualInterestRateParamName, this.nominalAnnualInterestRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName);
|
||||
actualChanges.put(nominalAnnualInterestRateParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
this.nominalAnnualInterestRate = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(interestCompoundingPeriodTypeParamName, this.interestCompoundingPeriodType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName);
|
||||
actualChanges.put(interestCompoundingPeriodTypeParamName, newValue);
|
||||
this.interestCompoundingPeriodType = SavingsCompoundingInterestPeriodType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(interestPostingPeriodTypeParamName, this.interestPostingPeriodType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestPostingPeriodTypeParamName);
|
||||
actualChanges.put(interestPostingPeriodTypeParamName, newValue);
|
||||
this.interestPostingPeriodType = SavingsPostingInterestPeriodType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(interestCalculationTypeParamName, this.interestCalculationType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestCalculationTypeParamName);
|
||||
actualChanges.put(interestCalculationTypeParamName, newValue);
|
||||
this.interestCalculationType = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(interestCalculationDaysInYearTypeParamName, this.interestCalculationDaysInYearType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestCalculationDaysInYearTypeParamName);
|
||||
actualChanges.put(interestCalculationDaysInYearTypeParamName, newValue);
|
||||
this.interestCalculationDaysInYearType = SavingsInterestCalculationDaysInYearType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamedDefaultingZeroToNull(minRequiredOpeningBalanceParamName, this.minRequiredOpeningBalance)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamedDefaultToNullIfZero(minRequiredOpeningBalanceParamName);
|
||||
actualChanges.put(minRequiredOpeningBalanceParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
this.minRequiredOpeningBalance = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamedDefaultingZeroToNull(lockinPeriodFrequencyParamName, this.lockinPeriodFrequency)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamedDefaultToNullIfZero(lockinPeriodFrequencyParamName);
|
||||
actualChanges.put(lockinPeriodFrequencyParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
this.lockinPeriodFrequency = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(lockinPeriodFrequencyTypeParamName, this.lockinPeriodFrequencyType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodFrequencyTypeParamName);
|
||||
actualChanges.put(lockinPeriodFrequencyTypeParamName, newValue);
|
||||
this.lockinPeriodFrequencyType = newValue != null ? SavingsPeriodFrequencyType.fromInt(newValue).getValue() : newValue;
|
||||
}
|
||||
|
||||
if (this.lockinPeriodFrequency == null) {
|
||||
this.lockinPeriodFrequencyType = null;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(withdrawalFeeForTransfersParamName, this.withdrawalFeeApplicableForTransfer)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(withdrawalFeeForTransfersParamName);
|
||||
actualChanges.put(withdrawalFeeForTransfersParamName, newValue);
|
||||
this.withdrawalFeeApplicableForTransfer = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(accountingRuleParamName, this.accountingRule)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(accountingRuleParamName);
|
||||
actualChanges.put(accountingRuleParamName, newValue);
|
||||
this.accountingRule = newValue;
|
||||
}
|
||||
|
||||
if (command.hasParameter(chargesParamName)) {
|
||||
final JsonArray jsonArray = command.arrayOfParameterNamed(chargesParamName);
|
||||
if (jsonArray != null) {
|
||||
actualChanges.put(chargesParamName, command.jsonFragment(chargesParamName));
|
||||
}
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(allowOverdraftParamName, this.allowOverdraft)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(allowOverdraftParamName);
|
||||
actualChanges.put(allowOverdraftParamName, newValue);
|
||||
this.allowOverdraft = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamedDefaultingZeroToNull(overdraftLimitParamName, this.overdraftLimit)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamedDefaultToNullIfZero(overdraftLimitParamName);
|
||||
actualChanges.put(overdraftLimitParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
this.overdraftLimit = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamedDefaultingZeroToNull(nominalAnnualInterestRateOverdraftParamName, this.nominalAnnualInterestRateOverdraft)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamedDefaultToNullIfZero(nominalAnnualInterestRateOverdraftParamName);
|
||||
actualChanges.put(nominalAnnualInterestRateOverdraftParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
this.nominalAnnualInterestRateOverdraft = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamedDefaultingZeroToNull(minOverdraftForInterestCalculationParamName, this.minOverdraftForInterestCalculation)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamedDefaultToNullIfZero(minOverdraftForInterestCalculationParamName);
|
||||
actualChanges.put(minOverdraftForInterestCalculationParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
this.minOverdraftForInterestCalculation = newValue;
|
||||
}
|
||||
|
||||
if (!this.allowOverdraft) {
|
||||
this.overdraftLimit = null;
|
||||
this.nominalAnnualInterestRateOverdraft = null;
|
||||
this.minOverdraftForInterestCalculation = null;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(enforceMinRequiredBalanceParamName, this.enforceMinRequiredBalance)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(enforceMinRequiredBalanceParamName);
|
||||
actualChanges.put(enforceMinRequiredBalanceParamName, newValue);
|
||||
this.enforceMinRequiredBalance = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamedDefaultingZeroToNull(minRequiredBalanceParamName, this.minRequiredBalance)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamedDefaultToNullIfZero(minRequiredBalanceParamName);
|
||||
actualChanges.put(minRequiredBalanceParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
this.minRequiredBalance = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(lienAllowedParamName, this.lienAllowed)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(lienAllowedParamName);
|
||||
actualChanges.put(lienAllowedParamName, newValue);
|
||||
this.lienAllowed = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamedDefaultingZeroToNull(maxAllowedLienLimitParamName, this.maxAllowedLienLimit)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamedDefaultToNullIfZero(maxAllowedLienLimitParamName);
|
||||
actualChanges.put(maxAllowedLienLimitParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
this.maxAllowedLienLimit = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamedDefaultingZeroToNull(minBalanceForInterestCalculationParamName, this.minBalanceForInterestCalculation)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamedDefaultToNullIfZero(minBalanceForInterestCalculationParamName);
|
||||
actualChanges.put(minBalanceForInterestCalculationParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
this.minBalanceForInterestCalculation = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(withHoldTaxParamName, this.withHoldTax)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(withHoldTaxParamName);
|
||||
actualChanges.put(withHoldTaxParamName, newValue);
|
||||
this.withHoldTax = newValue;
|
||||
}
|
||||
|
||||
if (this.withHoldTax) {
|
||||
if (this.taxGroup == null || command.isChangeInLongParameterNamed(taxGroupIdParamName, this.taxGroup.getId())) {
|
||||
final Long newValue = command.longValueOfParameterNamed(taxGroupIdParamName);
|
||||
actualChanges.put(taxGroupIdParamName, newValue);
|
||||
}
|
||||
} else {
|
||||
this.taxGroup = null;
|
||||
}
|
||||
|
||||
if (command.hasParameter(otherGlMappingsParamName)) {
|
||||
final String newValue = command.hasParameter(otherGlMappingsParamName) ? command.jsonFragment(otherGlMappingsParamName) : null;
|
||||
actualChanges.put(otherGlMappingsParamName, newValue);
|
||||
this.otherGlMappings = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(isDormancyTrackingActiveParamName, this.isDormancyTrackingActive)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(isDormancyTrackingActiveParamName);
|
||||
actualChanges.put(isDormancyTrackingActiveParamName, newValue);
|
||||
this.isDormancyTrackingActive = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInLongParameterNamed(daysToInactiveParamName, this.daysToInactive)) {
|
||||
final Long newValue = command.longValueOfParameterNamed(daysToInactiveParamName);
|
||||
actualChanges.put(daysToInactiveParamName, newValue);
|
||||
this.daysToInactive = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInLongParameterNamed(daysToDormancyParamName, this.daysToDormancy)) {
|
||||
final Long newValue = command.longValueOfParameterNamed(daysToDormancyParamName);
|
||||
actualChanges.put(daysToDormancyParamName, newValue);
|
||||
this.daysToDormancy = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInLongParameterNamed(daysToEscheatParamName, this.daysToEscheat)) {
|
||||
final Long newValue = command.longValueOfParameterNamed(daysToEscheatParamName);
|
||||
actualChanges.put(daysToEscheatParamName, newValue);
|
||||
this.daysToEscheat = newValue;
|
||||
}
|
||||
|
||||
// Enhanced fields
|
||||
if (command.isChangeInStringParameterNamed(accountTypeParamName, this.accountType)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(accountTypeParamName);
|
||||
actualChanges.put(accountTypeParamName, newValue);
|
||||
this.accountType = newValue;
|
||||
}
|
||||
if (command.isChangeInStringParameterNamed(customerSegmentParamName, this.customerSegment)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(customerSegmentParamName);
|
||||
actualChanges.put(customerSegmentParamName, newValue);
|
||||
this.customerSegment = newValue;
|
||||
}
|
||||
if (command.isChangeInStringParameterNamed(productCodeParamName, this.productCode)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(productCodeParamName);
|
||||
actualChanges.put(productCodeParamName, newValue);
|
||||
this.productCode = newValue;
|
||||
}
|
||||
if (command.isChangeInBooleanParameterNamed(introducerRequiredParamName, this.introducerRequired)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(introducerRequiredParamName);
|
||||
actualChanges.put(introducerRequiredParamName, newValue);
|
||||
this.introducerRequired = newValue;
|
||||
}
|
||||
if (command.isChangeInBooleanParameterNamed(shareLinkingEnabledParamName, this.shareLinkingEnabled)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(shareLinkingEnabledParamName);
|
||||
actualChanges.put(shareLinkingEnabledParamName, newValue);
|
||||
this.shareLinkingEnabled = newValue;
|
||||
}
|
||||
if (command.isChangeInBooleanParameterNamed(nominationFacilityParamName, this.nominationFacility)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(nominationFacilityParamName);
|
||||
actualChanges.put(nominationFacilityParamName, newValue);
|
||||
this.nominationFacility = newValue;
|
||||
}
|
||||
if (command.isChangeInBooleanParameterNamed(dormancyAlertParamName, this.dormancyAlert)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(dormancyAlertParamName);
|
||||
actualChanges.put(dormancyAlertParamName, newValue);
|
||||
this.dormancyAlert = newValue;
|
||||
}
|
||||
if (command.isChangeInBooleanParameterNamed(autoPostParamName, this.autoPost)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(autoPostParamName);
|
||||
actualChanges.put(autoPostParamName, newValue);
|
||||
this.autoPost = newValue;
|
||||
}
|
||||
if (command.isChangeInBooleanParameterNamed(enableLockinPeriodParamName, this.enableLockinPeriod)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(enableLockinPeriodParamName);
|
||||
actualChanges.put(enableLockinPeriodParamName, newValue);
|
||||
this.enableLockinPeriod = newValue;
|
||||
}
|
||||
|
||||
// New currency-step fields
|
||||
if (command.isChangeInBooleanParameterNamed(balanceSwapOptionParamName, this.balanceSwapOption)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(balanceSwapOptionParamName);
|
||||
actualChanges.put(balanceSwapOptionParamName, newValue);
|
||||
this.balanceSwapOption = newValue;
|
||||
}
|
||||
if (command.isChangeInBooleanParameterNamed(msmeParamName, this.msme)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(msmeParamName);
|
||||
actualChanges.put(msmeParamName, newValue);
|
||||
this.msme = newValue;
|
||||
}
|
||||
if (command.isChangeInBooleanParameterNamed(autoDebitFacilityParamName, this.autoDebitFacility)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(autoDebitFacilityParamName);
|
||||
actualChanges.put(autoDebitFacilityParamName, newValue);
|
||||
this.autoDebitFacility = newValue;
|
||||
}
|
||||
|
||||
// New OD-section fields
|
||||
if (command.isChangeInStringParameterNamed(avgBalanceCalcPeriodParamName, this.avgBalanceCalcPeriod)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(avgBalanceCalcPeriodParamName);
|
||||
actualChanges.put(avgBalanceCalcPeriodParamName, newValue);
|
||||
this.avgBalanceCalcPeriod = newValue;
|
||||
}
|
||||
if (command.isChangeInStringParameterNamed(validForPeriodParamName, this.validForPeriod)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(validForPeriodParamName);
|
||||
actualChanges.put(validForPeriodParamName, newValue);
|
||||
this.validForPeriod = newValue;
|
||||
}
|
||||
if (command.isChangeInBooleanParameterNamed(odAccountClosedZeroBalanceInDayClosingParamName, this.odAccountClosedZeroBalanceInDayClosing)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(odAccountClosedZeroBalanceInDayClosingParamName);
|
||||
actualChanges.put(odAccountClosedZeroBalanceInDayClosingParamName, newValue);
|
||||
this.odAccountClosedZeroBalanceInDayClosing = newValue;
|
||||
}
|
||||
// Clear OD-specific fields when overdraft is disabled
|
||||
if (!this.allowOverdraft) {
|
||||
this.avgBalanceCalcPeriod = null;
|
||||
this.validForPeriod = null;
|
||||
this.odAccountClosedZeroBalanceInDayClosing = false;
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
// Dormancy/misc getters needed by validator
|
||||
public Boolean isDormancyTrackingActive() { return this.isDormancyTrackingActive; }
|
||||
public Long getDaysToInactive() { return this.daysToInactive; }
|
||||
public Long getDaysToDormancy() { return this.daysToDormancy; }
|
||||
public Long getDaysToEscheat() { return this.daysToEscheat; }
|
||||
|
||||
// Getters and setters for enhanced fields
|
||||
public String getAccountType() { return accountType; }
|
||||
public void setAccountType(String accountType) { this.accountType = accountType; }
|
||||
public String getCustomerSegment() { return customerSegment; }
|
||||
public void setCustomerSegment(String customerSegment) { this.customerSegment = customerSegment; }
|
||||
public String getProductCode() { return productCode; }
|
||||
public void setProductCode(String productCode) { this.productCode = productCode; }
|
||||
public LocalDate getEffectiveDate() { return effectiveDate; }
|
||||
public void setEffectiveDate(LocalDate effectiveDate) { this.effectiveDate = effectiveDate; }
|
||||
public LocalDate getEffectiveTo() { return effectiveTo; }
|
||||
public void setEffectiveTo(LocalDate effectiveTo) { this.effectiveTo = effectiveTo; }
|
||||
public LocalDate getEndDate() { return endDate; }
|
||||
public void setEndDate(LocalDate endDate) { this.endDate = endDate; }
|
||||
public boolean isIntroducerRequired() { return introducerRequired; }
|
||||
public void setIntroducerRequired(boolean introducerRequired) { this.introducerRequired = introducerRequired; }
|
||||
public boolean isShareLinkingEnabled() { return shareLinkingEnabled; }
|
||||
public void setShareLinkingEnabled(boolean shareLinkingEnabled) { this.shareLinkingEnabled = shareLinkingEnabled; }
|
||||
public boolean isNominationFacility() { return nominationFacility; }
|
||||
public void setNominationFacility(boolean nominationFacility) { this.nominationFacility = nominationFacility; }
|
||||
public boolean isDormancyAlert() { return dormancyAlert; }
|
||||
public void setDormancyAlert(boolean dormancyAlert) { this.dormancyAlert = dormancyAlert; }
|
||||
public Integer getInterestCalculateSelector() { return interestCalculateSelector; }
|
||||
public void setInterestCalculateSelector(Integer interestCalculateSelector) { this.interestCalculateSelector = interestCalculateSelector; }
|
||||
public String getAveragePeriod() { return averagePeriod; }
|
||||
public void setAveragePeriod(String averagePeriod) { this.averagePeriod = averagePeriod; }
|
||||
public boolean isAutoPost() { return autoPost; }
|
||||
public void setAutoPost(boolean autoPost) { this.autoPost = autoPost; }
|
||||
public Integer getFrequencyFixDay() { return frequencyFixDay; }
|
||||
public void setFrequencyFixDay(Integer frequencyFixDay) { this.frequencyFixDay = frequencyFixDay; }
|
||||
public LocalDate getLastInterestDate() { return lastInterestDate; }
|
||||
public void setLastInterestDate(LocalDate lastInterestDate) { this.lastInterestDate = lastInterestDate; }
|
||||
public boolean isEnableLockinPeriod() { return enableLockinPeriod; }
|
||||
public void setEnableLockinPeriod(boolean enableLockinPeriod) { this.enableLockinPeriod = enableLockinPeriod; }
|
||||
public String getBalanceFrequency() { return balanceFrequency; }
|
||||
public void setBalanceFrequency(String balanceFrequency) { this.balanceFrequency = balanceFrequency; }
|
||||
public Boolean getAccountClosedZeroBalanceInDayClosing() { return accountClosedZeroBalanceInDayClosing; }
|
||||
public void setAccountClosedZeroBalanceInDayClosing(Boolean val) { this.accountClosedZeroBalanceInDayClosing = val; }
|
||||
|
||||
// New field getters/setters
|
||||
public boolean isBalanceSwapOption() { return balanceSwapOption; }
|
||||
public void setBalanceSwapOption(boolean balanceSwapOption) { this.balanceSwapOption = balanceSwapOption; }
|
||||
public boolean isMsme() { return msme; }
|
||||
public void setMsme(boolean msme) { this.msme = msme; }
|
||||
public boolean isAutoDebitFacility() { return autoDebitFacility; }
|
||||
public void setAutoDebitFacility(boolean autoDebitFacility) { this.autoDebitFacility = autoDebitFacility; }
|
||||
public String getAvgBalanceCalcPeriod() { return avgBalanceCalcPeriod; }
|
||||
public void setAvgBalanceCalcPeriod(String avgBalanceCalcPeriod) { this.avgBalanceCalcPeriod = avgBalanceCalcPeriod; }
|
||||
public String getValidForPeriod() { return validForPeriod; }
|
||||
public void setValidForPeriod(String validForPeriod) { this.validForPeriod = validForPeriod; }
|
||||
public boolean isOdAccountClosedZeroBalanceInDayClosing() { return odAccountClosedZeroBalanceInDayClosing; }
|
||||
public void setOdAccountClosedZeroBalanceInDayClosing(boolean val) { this.odAccountClosedZeroBalanceInDayClosing = val; }
|
||||
}
|
||||
+429
@@ -0,0 +1,429 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.domain;
|
||||
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accountFacilityConfigParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accountFacilityLimitsParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accountTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.allowOverdraftParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.autoPostParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.averagePeriodParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.chargesParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.currencyCodeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.customerSegmentParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToDormancyParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToEscheatParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToInactiveParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.depositLimitKycParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.descriptionParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.digitsAfterDecimalParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.dormancyAlertParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.effectiveDateParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.effectiveToParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.enableLockinPeriodParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.balanceSwapOptionParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.msmeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.autoDebitFacilityParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.avgBalanceCalcPeriodParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.validForPeriodParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.odAccountClosedZeroBalanceInDayClosingParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.endDateParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.enforceMinRequiredBalanceParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.frequencyFixDayParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.idParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.inMultiplesOfParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCalculateSelectorParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCalculationTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestPostingPeriodTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.introducerRequiredParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.isDormancyTrackingActiveParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lastInterestDateParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lienAllowedParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.maxAllowedLienLimitParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minBalanceForInterestCalculationParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minOverdraftForInterestCalculationParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minRequiredBalanceParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nameParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominationFacilityParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateOverdraftParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.otherGlMappingsParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.overdraftLimitParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.productCodeParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.shareLinkingEnabledParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.shortNameParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.taxGroupIdParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.apache.fineract.accounting.common.AccountingRuleType;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.exception.InvalidCurrencyException;
|
||||
import org.apache.fineract.portfolio.charge.domain.Charge;
|
||||
import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.charge.exception.ChargeCannotBeAppliedToException;
|
||||
import org.apache.fineract.portfolio.savings.SavingsCompoundingInterestPeriodType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationDaysInYearType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsPeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType;
|
||||
import org.apache.fineract.portfolio.tax.domain.TaxGroup;
|
||||
import org.apache.fineract.portfolio.tax.domain.TaxGroupRepositoryWrapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class CurrentProductAssembler {
|
||||
|
||||
private final ChargeRepositoryWrapper chargeRepository;
|
||||
private final TaxGroupRepositoryWrapper taxGroupRepository;
|
||||
|
||||
@Autowired
|
||||
public CurrentProductAssembler(final ChargeRepositoryWrapper chargeRepository,
|
||||
final TaxGroupRepositoryWrapper taxGroupRepository) {
|
||||
this.chargeRepository = chargeRepository;
|
||||
this.taxGroupRepository = taxGroupRepository;
|
||||
}
|
||||
|
||||
public CurrentProduct assemble(final JsonCommand command) {
|
||||
|
||||
final String name = command.stringValueOfParameterNamed(nameParamName);
|
||||
final String shortName = command.stringValueOfParameterNamed(shortNameParamName);
|
||||
final String description = command.stringValueOfParameterNamedAllowingNull(descriptionParamName);
|
||||
|
||||
final String currencyCode = command.stringValueOfParameterNamed(currencyCodeParamName);
|
||||
final Integer digitsAfterDecimal = command.integerValueOfParameterNamed(digitsAfterDecimalParamName);
|
||||
final Integer inMultiplesOf = command.integerValueOfParameterNamed(inMultiplesOfParamName);
|
||||
final MonetaryCurrency currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal, inMultiplesOf);
|
||||
|
||||
BigDecimal interestRate = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateParamName);
|
||||
if (interestRate == null) {
|
||||
interestRate = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
SavingsCompoundingInterestPeriodType interestCompoundingPeriodType = SavingsCompoundingInterestPeriodType.DAILY;
|
||||
final Integer interestPeriodTypeValue = command.integerValueOfParameterNamed(interestCompoundingPeriodTypeParamName);
|
||||
if (interestPeriodTypeValue != null) {
|
||||
interestCompoundingPeriodType = SavingsCompoundingInterestPeriodType.fromInt(interestPeriodTypeValue);
|
||||
}
|
||||
|
||||
SavingsPostingInterestPeriodType interestPostingPeriodType = null;
|
||||
final Integer interestPostingPeriodTypeValue = command.integerValueOfParameterNamed(interestPostingPeriodTypeParamName);
|
||||
if (interestPostingPeriodTypeValue != null) {
|
||||
interestPostingPeriodType = SavingsPostingInterestPeriodType.fromInt(interestPostingPeriodTypeValue);
|
||||
}
|
||||
|
||||
SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.DAILY_BALANCE;
|
||||
final Integer interestCalculationTypeValue = command.integerValueOfParameterNamed(interestCalculationTypeParamName);
|
||||
if (interestCalculationTypeValue != null) {
|
||||
interestCalculationType = SavingsInterestCalculationType.fromInt(interestCalculationTypeValue);
|
||||
}
|
||||
|
||||
SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType = SavingsInterestCalculationDaysInYearType.DAYS_365;
|
||||
final Integer interestCalculationDaysInYearTypeValue = command.integerValueOfParameterNamed(interestCalculationDaysInYearTypeParamName);
|
||||
if (interestCalculationDaysInYearTypeValue != null) {
|
||||
interestCalculationDaysInYearType = SavingsInterestCalculationDaysInYearType.fromInt(interestCalculationDaysInYearTypeValue);
|
||||
}
|
||||
|
||||
final BigDecimal minRequiredOpeningBalance = command.bigDecimalValueOfParameterNamedDefaultToNullIfZero(minRequiredOpeningBalanceParamName);
|
||||
|
||||
final Integer lockinPeriodFrequency = command.integerValueOfParameterNamedDefaultToNullIfZero(lockinPeriodFrequencyParamName);
|
||||
SavingsPeriodFrequencyType lockinPeriodFrequencyType = null;
|
||||
final Integer lockinPeriodFrequencyTypeValue = command.integerValueOfParameterNamed(lockinPeriodFrequencyTypeParamName);
|
||||
if (lockinPeriodFrequencyTypeValue != null) {
|
||||
lockinPeriodFrequencyType = SavingsPeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
|
||||
}
|
||||
|
||||
boolean isWithdrawalFeeApplicableForTransfer = false;
|
||||
if (command.parameterExists(withdrawalFeeForTransfersParamName)) {
|
||||
isWithdrawalFeeApplicableForTransfer = command.booleanPrimitiveValueOfParameterNamed(withdrawalFeeForTransfersParamName);
|
||||
}
|
||||
|
||||
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(command.integerValueOfParameterNamed("accountingRule"));
|
||||
|
||||
final Set<Charge> charges = assembleListOfCurrentProductCharges(command, currencyCode);
|
||||
|
||||
boolean allowOverdraft = false;
|
||||
if (command.parameterExists(allowOverdraftParamName)) {
|
||||
allowOverdraft = command.booleanPrimitiveValueOfParameterNamed(allowOverdraftParamName);
|
||||
}
|
||||
|
||||
BigDecimal overdraftLimit = BigDecimal.ZERO;
|
||||
if (command.parameterExists(overdraftLimitParamName)) {
|
||||
overdraftLimit = command.bigDecimalValueOfParameterNamed(overdraftLimitParamName);
|
||||
}
|
||||
|
||||
BigDecimal nominalAnnualInterestRateOverdraft = BigDecimal.ZERO;
|
||||
if (command.parameterExists(nominalAnnualInterestRateOverdraftParamName)) {
|
||||
nominalAnnualInterestRateOverdraft = command.bigDecimalValueOfParameterNamed(nominalAnnualInterestRateOverdraftParamName);
|
||||
}
|
||||
|
||||
BigDecimal minOverdraftForInterestCalculation = BigDecimal.ZERO;
|
||||
if (command.parameterExists(minOverdraftForInterestCalculationParamName)) {
|
||||
minOverdraftForInterestCalculation = command.bigDecimalValueOfParameterNamed(minOverdraftForInterestCalculationParamName);
|
||||
}
|
||||
|
||||
boolean enforceMinRequiredBalance = false;
|
||||
if (command.parameterExists(enforceMinRequiredBalanceParamName)) {
|
||||
enforceMinRequiredBalance = command.booleanPrimitiveValueOfParameterNamed(enforceMinRequiredBalanceParamName);
|
||||
}
|
||||
|
||||
BigDecimal minRequiredBalance = BigDecimal.ZERO;
|
||||
if (command.parameterExists(minRequiredBalanceParamName)) {
|
||||
minRequiredBalance = command.bigDecimalValueOfParameterNamed(minRequiredBalanceParamName);
|
||||
}
|
||||
|
||||
boolean lienAllowed = false;
|
||||
if (command.parameterExists(lienAllowedParamName)) {
|
||||
lienAllowed = command.booleanPrimitiveValueOfParameterNamed(lienAllowedParamName);
|
||||
}
|
||||
|
||||
BigDecimal maxAllowedLienLimit = BigDecimal.ZERO;
|
||||
if (command.parameterExists(maxAllowedLienLimitParamName)) {
|
||||
maxAllowedLienLimit = command.bigDecimalValueOfParameterNamedDefaultToNullIfZero(maxAllowedLienLimitParamName);
|
||||
}
|
||||
|
||||
final BigDecimal minBalanceForInterestCalculation = command.bigDecimalValueOfParameterNamedDefaultToNullIfZero(minBalanceForInterestCalculationParamName);
|
||||
|
||||
boolean withHoldTax = command.booleanPrimitiveValueOfParameterNamed(withHoldTaxParamName);
|
||||
final TaxGroup taxGroup = assembleTaxGroup(command);
|
||||
|
||||
final Boolean isDormancyTrackingActive = command.booleanObjectValueOfParameterNamed(isDormancyTrackingActiveParamName);
|
||||
final Long daysToInactive = command.longValueOfParameterNamed(daysToInactiveParamName);
|
||||
final Long daysToDormancy = command.longValueOfParameterNamed(daysToDormancyParamName);
|
||||
final Long daysToEscheat = command.longValueOfParameterNamed(daysToEscheatParamName);
|
||||
final String otherGlMappings = command.hasParameter(otherGlMappingsParamName) ? command.jsonFragment(otherGlMappingsParamName) : null;
|
||||
|
||||
CurrentProduct product = CurrentProduct.createNew(name, shortName, description, currency, interestRate,
|
||||
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType, isWithdrawalFeeApplicableForTransfer, accountingRuleType, charges,
|
||||
allowOverdraft, overdraftLimit, enforceMinRequiredBalance, minRequiredBalance, lienAllowed,
|
||||
maxAllowedLienLimit, minBalanceForInterestCalculation, nominalAnnualInterestRateOverdraft,
|
||||
minOverdraftForInterestCalculation, withHoldTax, taxGroup, otherGlMappings,
|
||||
isDormancyTrackingActive, daysToInactive, daysToDormancy, daysToEscheat);
|
||||
|
||||
// Set enhanced fields
|
||||
if (command.parameterExists(accountTypeParamName)) {
|
||||
product.setAccountType(command.stringValueOfParameterNamed(accountTypeParamName));
|
||||
}
|
||||
if (command.parameterExists(customerSegmentParamName)) {
|
||||
product.setCustomerSegment(command.stringValueOfParameterNamed(customerSegmentParamName));
|
||||
}
|
||||
if (command.parameterExists(productCodeParamName)) {
|
||||
product.setProductCode(command.stringValueOfParameterNamed(productCodeParamName));
|
||||
}
|
||||
if (command.parameterExists(effectiveDateParamName)) {
|
||||
product.setEffectiveDate(command.localDateValueOfParameterNamed(effectiveDateParamName));
|
||||
}
|
||||
if (command.parameterExists(effectiveToParamName)) {
|
||||
product.setEffectiveTo(command.localDateValueOfParameterNamed(effectiveToParamName));
|
||||
}
|
||||
if (command.parameterExists(endDateParamName)) {
|
||||
product.setEndDate(command.localDateValueOfParameterNamed(endDateParamName));
|
||||
}
|
||||
if (command.parameterExists(introducerRequiredParamName)) {
|
||||
product.setIntroducerRequired(command.booleanPrimitiveValueOfParameterNamed(introducerRequiredParamName));
|
||||
}
|
||||
if (command.parameterExists(shareLinkingEnabledParamName)) {
|
||||
product.setShareLinkingEnabled(command.booleanPrimitiveValueOfParameterNamed(shareLinkingEnabledParamName));
|
||||
}
|
||||
if (command.parameterExists(nominationFacilityParamName)) {
|
||||
product.setNominationFacility(command.booleanPrimitiveValueOfParameterNamed(nominationFacilityParamName));
|
||||
}
|
||||
if (command.parameterExists(dormancyAlertParamName)) {
|
||||
product.setDormancyAlert(command.booleanPrimitiveValueOfParameterNamed(dormancyAlertParamName));
|
||||
}
|
||||
if (command.parameterExists(interestCalculateSelectorParamName)) {
|
||||
product.setInterestCalculateSelector(command.integerValueOfParameterNamed(interestCalculateSelectorParamName));
|
||||
}
|
||||
if (command.parameterExists(averagePeriodParamName)) {
|
||||
product.setAveragePeriod(command.stringValueOfParameterNamed(averagePeriodParamName));
|
||||
}
|
||||
if (command.parameterExists(autoPostParamName)) {
|
||||
product.setAutoPost(command.booleanPrimitiveValueOfParameterNamed(autoPostParamName));
|
||||
}
|
||||
if (command.parameterExists(frequencyFixDayParamName)) {
|
||||
product.setFrequencyFixDay(command.integerValueOfParameterNamed(frequencyFixDayParamName));
|
||||
}
|
||||
if (command.parameterExists(lastInterestDateParamName)) {
|
||||
product.setLastInterestDate(command.localDateValueOfParameterNamed(lastInterestDateParamName));
|
||||
}
|
||||
if (command.parameterExists(enableLockinPeriodParamName)) {
|
||||
product.setEnableLockinPeriod(command.booleanPrimitiveValueOfParameterNamed(enableLockinPeriodParamName));
|
||||
}
|
||||
if (command.parameterExists("balanceFrequency")) {
|
||||
product.setBalanceFrequency(command.stringValueOfParameterNamed("balanceFrequency"));
|
||||
}
|
||||
if (command.parameterExists("accountClosedZeroBalanceInDayClosing")) {
|
||||
product.setAccountClosedZeroBalanceInDayClosing(command.booleanObjectValueOfParameterNamed("accountClosedZeroBalanceInDayClosing"));
|
||||
}
|
||||
|
||||
// New currency-step fields
|
||||
if (command.parameterExists(balanceSwapOptionParamName)) {
|
||||
product.setBalanceSwapOption(command.booleanPrimitiveValueOfParameterNamed(balanceSwapOptionParamName));
|
||||
}
|
||||
if (command.parameterExists(msmeParamName)) {
|
||||
product.setMsme(command.booleanPrimitiveValueOfParameterNamed(msmeParamName));
|
||||
}
|
||||
if (command.parameterExists(autoDebitFacilityParamName)) {
|
||||
product.setAutoDebitFacility(command.booleanPrimitiveValueOfParameterNamed(autoDebitFacilityParamName));
|
||||
}
|
||||
|
||||
// New OD-section fields (only set when overdraft is allowed)
|
||||
if (allowOverdraft) {
|
||||
if (command.parameterExists(avgBalanceCalcPeriodParamName)) {
|
||||
product.setAvgBalanceCalcPeriod(command.stringValueOfParameterNamed(avgBalanceCalcPeriodParamName));
|
||||
}
|
||||
if (command.parameterExists(validForPeriodParamName)) {
|
||||
product.setValidForPeriod(command.stringValueOfParameterNamed(validForPeriodParamName));
|
||||
}
|
||||
if (command.parameterExists(odAccountClosedZeroBalanceInDayClosingParamName)) {
|
||||
product.setOdAccountClosedZeroBalanceInDayClosing(command.booleanPrimitiveValueOfParameterNamed(odAccountClosedZeroBalanceInDayClosingParamName));
|
||||
}
|
||||
}
|
||||
|
||||
return product;
|
||||
}
|
||||
|
||||
public Set<Charge> assembleListOfCurrentProductCharges(final JsonCommand command, final String currencyCode) {
|
||||
final Set<Charge> charges = new HashSet<>();
|
||||
if (command.parameterExists(chargesParamName)) {
|
||||
final JsonArray chargesArray = command.arrayOfParameterNamed(chargesParamName);
|
||||
if (chargesArray != null) {
|
||||
for (int i = 0; i < chargesArray.size(); i++) {
|
||||
final JsonObject jsonObject = chargesArray.get(i).getAsJsonObject();
|
||||
if (jsonObject.has(idParamName)) {
|
||||
final Long id = jsonObject.get(idParamName).getAsLong();
|
||||
final Charge charge = this.chargeRepository.findOneWithNotFoundDetection(id);
|
||||
if (!charge.isSavingsCharge()) {
|
||||
final String errorMessage = "Charge with identifier " + charge.getId()
|
||||
+ " cannot be applied to Current product.";
|
||||
throw new ChargeCannotBeAppliedToException("current.product", errorMessage, charge.getId());
|
||||
}
|
||||
if (!currencyCode.equals(charge.getCurrencyCode())) {
|
||||
final String errorMessage = "Charge and Current Product must have the same currency.";
|
||||
throw new InvalidCurrencyException("charge", "attach.to.current.product", errorMessage);
|
||||
}
|
||||
charges.add(charge);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return charges;
|
||||
}
|
||||
|
||||
public TaxGroup assembleTaxGroup(final JsonCommand command) {
|
||||
final Long taxGroupId = command.longValueOfParameterNamed(taxGroupIdParamName);
|
||||
TaxGroup taxGroup = null;
|
||||
if (taxGroupId != null) {
|
||||
taxGroup = this.taxGroupRepository.findOneWithNotFoundDetection(taxGroupId);
|
||||
}
|
||||
return taxGroup;
|
||||
}
|
||||
|
||||
public CurrentProductFacilityConfig assembleAccountFacilityConfig(final JsonCommand command, final CurrentProduct product) {
|
||||
if (!command.hasParameter(accountFacilityConfigParamName)) {
|
||||
return null;
|
||||
}
|
||||
JsonElement facilityConfigElement = command.parsedJson().getAsJsonObject().get(accountFacilityConfigParamName);
|
||||
if (facilityConfigElement == null || facilityConfigElement.isJsonNull()) {
|
||||
return null;
|
||||
}
|
||||
final JsonObject facilityConfigJson = facilityConfigElement.getAsJsonObject();
|
||||
CurrentProductFacilityConfig config = new CurrentProductFacilityConfig(product);
|
||||
config.setAtmFacility(facilityConfigJson.has("atmFacility") ? facilityConfigJson.get("atmFacility").getAsBoolean() : false);
|
||||
config.setAtmWithdrawalFacility(facilityConfigJson.has("atmWithdrawalFacility") ? facilityConfigJson.get("atmWithdrawalFacility").getAsBoolean() : false);
|
||||
config.setUpiFacility(facilityConfigJson.has("upiFacility") ? facilityConfigJson.get("upiFacility").getAsBoolean() : false);
|
||||
config.setPosTransactionsFacility(facilityConfigJson.has("posTransactionsFacility") ? facilityConfigJson.get("posTransactionsFacility").getAsBoolean() : false);
|
||||
config.setChequeBook(facilityConfigJson.has("chequeBook") ? facilityConfigJson.get("chequeBook").getAsBoolean() : false);
|
||||
config.setImpsFacility(facilityConfigJson.has("impsFacility") ? facilityConfigJson.get("impsFacility").getAsBoolean() : false);
|
||||
config.setSmsAlerts(facilityConfigJson.has("smsAlerts") ? facilityConfigJson.get("smsAlerts").getAsBoolean() : false);
|
||||
config.setBbpsFacility(facilityConfigJson.has("bbpsFacility") ? facilityConfigJson.get("bbpsFacility").getAsBoolean() : false);
|
||||
config.setInsuranceCover(facilityConfigJson.has("insuranceCover") ? facilityConfigJson.get("insuranceCover").getAsBoolean() : false);
|
||||
config.setBepgFacility(facilityConfigJson.has("bepgFacility") ? facilityConfigJson.get("bepgFacility").getAsBoolean() : false);
|
||||
config.setNeftFacility(facilityConfigJson.has("neftFacility") ? facilityConfigJson.get("neftFacility").getAsBoolean() : false);
|
||||
config.setRtgsFacility(facilityConfigJson.has("rtgsFacility") ? facilityConfigJson.get("rtgsFacility").getAsBoolean() : false);
|
||||
config.setInterBankTotalCapFacility(facilityConfigJson.has("interBankTotalCapFacility") ? facilityConfigJson.get("interBankTotalCapFacility").getAsBoolean() : false);
|
||||
config.setWithdrawalFacility(facilityConfigJson.has("withdrawalFacility") ? facilityConfigJson.get("withdrawalFacility").getAsBoolean() : false);
|
||||
config.setDepositFacilityKyc(facilityConfigJson.has("depositFacilityKyc") ? facilityConfigJson.get("depositFacilityKyc").getAsBoolean() : false);
|
||||
config.setVirtualDebitCard(facilityConfigJson.has("virtualDebitCard") ? facilityConfigJson.get("virtualDebitCard").getAsBoolean() : false);
|
||||
return config;
|
||||
}
|
||||
|
||||
public Set<CurrentProductFacilityLimit> assembleAccountFacilityLimits(final JsonCommand command, final CurrentProduct product) {
|
||||
final Set<CurrentProductFacilityLimit> limits = new HashSet<>();
|
||||
if (!command.hasParameter(accountFacilityLimitsParamName)) {
|
||||
return limits;
|
||||
}
|
||||
final JsonArray limitsArray = command.arrayOfParameterNamed(accountFacilityLimitsParamName);
|
||||
if (limitsArray == null) {
|
||||
return limits;
|
||||
}
|
||||
for (int i = 0; i < limitsArray.size(); i++) {
|
||||
final JsonObject limitJson = limitsArray.get(i).getAsJsonObject();
|
||||
limits.add(CurrentProductFacilityLimit.create(product,
|
||||
limitJson.has("limitType") ? limitJson.get("limitType").getAsString() : null,
|
||||
limitJson.has("generalLimit") ? limitJson.get("generalLimit").getAsString() : null,
|
||||
limitJson.has("minorAccountLimit") ? limitJson.get("minorAccountLimit").getAsString() : null,
|
||||
limitJson.has("smallSavingLimit") ? limitJson.get("smallSavingLimit").getAsString() : null));
|
||||
}
|
||||
return limits;
|
||||
}
|
||||
|
||||
public CurrentProductDepositLimitKyc assembleDepositLimitKyc(final JsonCommand command, final CurrentProduct product) {
|
||||
if (!command.hasParameter(depositLimitKycParamName)) {
|
||||
return null;
|
||||
}
|
||||
JsonElement kycElement = command.parsedJson().getAsJsonObject().get(depositLimitKycParamName);
|
||||
if (kycElement == null || kycElement.isJsonNull()) {
|
||||
return null;
|
||||
}
|
||||
final JsonObject kycJson = kycElement.getAsJsonObject();
|
||||
CurrentProductDepositLimitKyc kyc = new CurrentProductDepositLimitKyc(product);
|
||||
if (kycJson.has("general")) {
|
||||
final JsonObject generalJson = kycJson.getAsJsonObject("general");
|
||||
kyc.setGeneralKycType(generalJson.has("kycType") ? generalJson.get("kycType").getAsString() : null);
|
||||
kyc.setGeneralLimit(generalJson.has("limit") ? generalJson.get("limit").getAsString() : null);
|
||||
}
|
||||
if (kycJson.has("minor")) {
|
||||
final JsonObject minorJson = kycJson.getAsJsonObject("minor");
|
||||
kyc.setMinorKycType(minorJson.has("kycType") ? minorJson.get("kycType").getAsString() : null);
|
||||
kyc.setMinorLimit(minorJson.has("limit") ? minorJson.get("limit").getAsLong() : null);
|
||||
}
|
||||
if (kycJson.has("smallSaving")) {
|
||||
final JsonObject smallSavingJson = kycJson.getAsJsonObject("smallSaving");
|
||||
kyc.setSmallSavingKycType(smallSavingJson.has("kycType") ? smallSavingJson.get("kycType").getAsString() : null);
|
||||
kyc.setSmallSavingLimit(smallSavingJson.has("limit") ? smallSavingJson.get("limit").getAsLong() : null);
|
||||
}
|
||||
return kyc;
|
||||
}
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.domain;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.time.LocalDateTime;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_current_product_deposit_limit_kyc")
|
||||
public class CurrentProductDepositLimitKyc extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "current_product_id", nullable = false)
|
||||
private CurrentProduct currentProduct;
|
||||
|
||||
@Column(name = "general_kyc_type", length = 50)
|
||||
private String generalKycType;
|
||||
|
||||
@Column(name = "general_limit", length = 50)
|
||||
private String generalLimit;
|
||||
|
||||
@Column(name = "minor_kyc_type", length = 50)
|
||||
private String minorKycType;
|
||||
|
||||
@Column(name = "minor_limit")
|
||||
private Long minorLimit;
|
||||
|
||||
@Column(name = "small_saving_kyc_type", length = 50)
|
||||
private String smallSavingKycType;
|
||||
|
||||
@Column(name = "small_saving_limit")
|
||||
private Long smallSavingLimit;
|
||||
|
||||
@Column(name = "created_date", nullable = false)
|
||||
private LocalDateTime createdDate;
|
||||
|
||||
protected CurrentProductDepositLimitKyc() {
|
||||
this.createdDate = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public CurrentProductDepositLimitKyc(CurrentProduct currentProduct) {
|
||||
this();
|
||||
this.currentProduct = currentProduct;
|
||||
}
|
||||
|
||||
public CurrentProduct getCurrentProduct() { return currentProduct; }
|
||||
public void setCurrentProduct(CurrentProduct currentProduct) { this.currentProduct = currentProduct; }
|
||||
public String getGeneralKycType() { return generalKycType; }
|
||||
public void setGeneralKycType(String generalKycType) { this.generalKycType = generalKycType; }
|
||||
public String getGeneralLimit() { return generalLimit; }
|
||||
public void setGeneralLimit(String generalLimit) { this.generalLimit = generalLimit; }
|
||||
public String getMinorKycType() { return minorKycType; }
|
||||
public void setMinorKycType(String minorKycType) { this.minorKycType = minorKycType; }
|
||||
public Long getMinorLimit() { return minorLimit; }
|
||||
public void setMinorLimit(Long minorLimit) { this.minorLimit = minorLimit; }
|
||||
public String getSmallSavingKycType() { return smallSavingKycType; }
|
||||
public void setSmallSavingKycType(String smallSavingKycType) { this.smallSavingKycType = smallSavingKycType; }
|
||||
public Long getSmallSavingLimit() { return smallSavingLimit; }
|
||||
public void setSmallSavingLimit(Long smallSavingLimit) { this.smallSavingLimit = smallSavingLimit; }
|
||||
public LocalDateTime getCreatedDate() { return createdDate; }
|
||||
|
||||
public void updateFrom(CurrentProductDepositLimitKyc other) {
|
||||
this.generalKycType = other.getGeneralKycType();
|
||||
this.generalLimit = other.getGeneralLimit();
|
||||
this.minorKycType = other.getMinorKycType();
|
||||
this.minorLimit = other.getMinorLimit();
|
||||
this.smallSavingKycType = other.getSmallSavingKycType();
|
||||
this.smallSavingLimit = other.getSmallSavingLimit();
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface CurrentProductDepositLimitKycRepository extends JpaRepository<CurrentProductDepositLimitKyc, Long> {
|
||||
|
||||
CurrentProductDepositLimitKyc findByCurrentProductId(Long currentProductId);
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.domain;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.time.LocalDateTime;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_current_product_facility_config")
|
||||
public class CurrentProductFacilityConfig extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "current_product_id", nullable = false)
|
||||
private CurrentProduct currentProduct;
|
||||
|
||||
@Column(name = "atm_facility")
|
||||
private Boolean atmFacility = false;
|
||||
|
||||
@Column(name = "atm_withdrawal_facility")
|
||||
private Boolean atmWithdrawalFacility = false;
|
||||
|
||||
@Column(name = "upi_facility")
|
||||
private Boolean upiFacility = false;
|
||||
|
||||
@Column(name = "pos_transactions_facility")
|
||||
private Boolean posTransactionsFacility = false;
|
||||
|
||||
@Column(name = "cheque_book")
|
||||
private Boolean chequeBook = false;
|
||||
|
||||
@Column(name = "imps_facility")
|
||||
private Boolean impsFacility = false;
|
||||
|
||||
@Column(name = "sms_alerts")
|
||||
private Boolean smsAlerts = false;
|
||||
|
||||
@Column(name = "bbps_facility")
|
||||
private Boolean bbpsFacility = false;
|
||||
|
||||
@Column(name = "insurance_cover")
|
||||
private Boolean insuranceCover = false;
|
||||
|
||||
@Column(name = "bepg_facility")
|
||||
private Boolean bepgFacility = false;
|
||||
|
||||
@Column(name = "neft_facility")
|
||||
private Boolean neftFacility = false;
|
||||
|
||||
@Column(name = "rtgs_facility")
|
||||
private Boolean rtgsFacility = false;
|
||||
|
||||
@Column(name = "inter_bank_total_cap_facility")
|
||||
private Boolean interBankTotalCapFacility = false;
|
||||
|
||||
@Column(name = "withdrawal_facility")
|
||||
private Boolean withdrawalFacility = false;
|
||||
|
||||
@Column(name = "deposit_facility_kyc")
|
||||
private Boolean depositFacilityKyc = false;
|
||||
|
||||
@Column(name = "virtual_debit_card")
|
||||
private Boolean virtualDebitCard = false;
|
||||
|
||||
@Column(name = "created_date", nullable = false)
|
||||
private LocalDateTime createdDate;
|
||||
|
||||
protected CurrentProductFacilityConfig() {
|
||||
this.createdDate = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public CurrentProductFacilityConfig(CurrentProduct currentProduct) {
|
||||
this();
|
||||
this.currentProduct = currentProduct;
|
||||
}
|
||||
|
||||
public CurrentProduct getCurrentProduct() { return currentProduct; }
|
||||
public void setCurrentProduct(CurrentProduct currentProduct) { this.currentProduct = currentProduct; }
|
||||
|
||||
public Boolean getAtmFacility() { return atmFacility; }
|
||||
public void setAtmFacility(Boolean v) { this.atmFacility = v != null ? v : false; }
|
||||
public Boolean getAtmWithdrawalFacility() { return atmWithdrawalFacility; }
|
||||
public void setAtmWithdrawalFacility(Boolean v) { this.atmWithdrawalFacility = v != null ? v : false; }
|
||||
public Boolean getUpiFacility() { return upiFacility; }
|
||||
public void setUpiFacility(Boolean v) { this.upiFacility = v != null ? v : false; }
|
||||
public Boolean getPosTransactionsFacility() { return posTransactionsFacility; }
|
||||
public void setPosTransactionsFacility(Boolean v) { this.posTransactionsFacility = v != null ? v : false; }
|
||||
public Boolean getChequeBook() { return chequeBook; }
|
||||
public void setChequeBook(Boolean v) { this.chequeBook = v != null ? v : false; }
|
||||
public Boolean getImpsFacility() { return impsFacility; }
|
||||
public void setImpsFacility(Boolean v) { this.impsFacility = v != null ? v : false; }
|
||||
public Boolean getSmsAlerts() { return smsAlerts; }
|
||||
public void setSmsAlerts(Boolean v) { this.smsAlerts = v != null ? v : false; }
|
||||
public Boolean getBbpsFacility() { return bbpsFacility; }
|
||||
public void setBbpsFacility(Boolean v) { this.bbpsFacility = v != null ? v : false; }
|
||||
public Boolean getInsuranceCover() { return insuranceCover; }
|
||||
public void setInsuranceCover(Boolean v) { this.insuranceCover = v != null ? v : false; }
|
||||
public Boolean getBepgFacility() { return bepgFacility; }
|
||||
public void setBepgFacility(Boolean v) { this.bepgFacility = v != null ? v : false; }
|
||||
public Boolean getNeftFacility() { return neftFacility; }
|
||||
public void setNeftFacility(Boolean v) { this.neftFacility = v != null ? v : false; }
|
||||
public Boolean getRtgsFacility() { return rtgsFacility; }
|
||||
public void setRtgsFacility(Boolean v) { this.rtgsFacility = v != null ? v : false; }
|
||||
public Boolean getInterBankTotalCapFacility() { return interBankTotalCapFacility; }
|
||||
public void setInterBankTotalCapFacility(Boolean v) { this.interBankTotalCapFacility = v != null ? v : false; }
|
||||
public Boolean getWithdrawalFacility() { return withdrawalFacility; }
|
||||
public void setWithdrawalFacility(Boolean v) { this.withdrawalFacility = v != null ? v : false; }
|
||||
public Boolean getDepositFacilityKyc() { return depositFacilityKyc; }
|
||||
public void setDepositFacilityKyc(Boolean v) { this.depositFacilityKyc = v != null ? v : false; }
|
||||
public Boolean getVirtualDebitCard() { return virtualDebitCard; }
|
||||
public void setVirtualDebitCard(Boolean v) { this.virtualDebitCard = v != null ? v : false; }
|
||||
public LocalDateTime getCreatedDate() { return createdDate; }
|
||||
|
||||
public void updateFrom(CurrentProductFacilityConfig other) {
|
||||
this.atmFacility = other.getAtmFacility();
|
||||
this.atmWithdrawalFacility = other.getAtmWithdrawalFacility();
|
||||
this.upiFacility = other.getUpiFacility();
|
||||
this.posTransactionsFacility = other.getPosTransactionsFacility();
|
||||
this.chequeBook = other.getChequeBook();
|
||||
this.impsFacility = other.getImpsFacility();
|
||||
this.smsAlerts = other.getSmsAlerts();
|
||||
this.bbpsFacility = other.getBbpsFacility();
|
||||
this.insuranceCover = other.getInsuranceCover();
|
||||
this.bepgFacility = other.getBepgFacility();
|
||||
this.neftFacility = other.getNeftFacility();
|
||||
this.rtgsFacility = other.getRtgsFacility();
|
||||
this.interBankTotalCapFacility = other.getInterBankTotalCapFacility();
|
||||
this.withdrawalFacility = other.getWithdrawalFacility();
|
||||
this.depositFacilityKyc = other.getDepositFacilityKyc();
|
||||
this.virtualDebitCard = other.getVirtualDebitCard();
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface CurrentProductFacilityConfigRepository extends JpaRepository<CurrentProductFacilityConfig, Long> {
|
||||
|
||||
CurrentProductFacilityConfig findByCurrentProductId(Long currentProductId);
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.domain;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.time.LocalDateTime;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_current_product_facility_limits")
|
||||
public class CurrentProductFacilityLimit extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "current_product_id", nullable = false)
|
||||
private CurrentProduct currentProduct;
|
||||
|
||||
@Column(name = "limit_type", length = 100, nullable = false)
|
||||
private String limitType;
|
||||
|
||||
@Column(name = "general_limit", length = 50)
|
||||
private String generalLimit;
|
||||
|
||||
@Column(name = "minor_account_limit", length = 50)
|
||||
private String minorAccountLimit;
|
||||
|
||||
@Column(name = "small_saving_limit", length = 50)
|
||||
private String smallSavingLimit;
|
||||
|
||||
@Column(name = "created_date", nullable = false)
|
||||
private LocalDateTime createdDate;
|
||||
|
||||
protected CurrentProductFacilityLimit() {
|
||||
this.createdDate = LocalDateTime.now();
|
||||
}
|
||||
|
||||
private CurrentProductFacilityLimit(CurrentProduct currentProduct, String limitType,
|
||||
String generalLimit, String minorAccountLimit, String smallSavingLimit) {
|
||||
this();
|
||||
this.currentProduct = currentProduct;
|
||||
this.limitType = limitType;
|
||||
this.generalLimit = generalLimit;
|
||||
this.minorAccountLimit = minorAccountLimit;
|
||||
this.smallSavingLimit = smallSavingLimit;
|
||||
}
|
||||
|
||||
public static CurrentProductFacilityLimit create(CurrentProduct currentProduct, String limitType,
|
||||
String generalLimit, String minorAccountLimit, String smallSavingLimit) {
|
||||
return new CurrentProductFacilityLimit(currentProduct, limitType, generalLimit, minorAccountLimit, smallSavingLimit);
|
||||
}
|
||||
|
||||
public CurrentProduct getCurrentProduct() { return currentProduct; }
|
||||
public void setCurrentProduct(CurrentProduct currentProduct) { this.currentProduct = currentProduct; }
|
||||
public String getLimitType() { return limitType; }
|
||||
public void setLimitType(String limitType) { this.limitType = limitType; }
|
||||
public String getGeneralLimit() { return generalLimit; }
|
||||
public void setGeneralLimit(String generalLimit) { this.generalLimit = generalLimit; }
|
||||
public String getMinorAccountLimit() { return minorAccountLimit; }
|
||||
public void setMinorAccountLimit(String minorAccountLimit) { this.minorAccountLimit = minorAccountLimit; }
|
||||
public String getSmallSavingLimit() { return smallSavingLimit; }
|
||||
public void setSmallSavingLimit(String smallSavingLimit) { this.smallSavingLimit = smallSavingLimit; }
|
||||
public LocalDateTime getCreatedDate() { return createdDate; }
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.domain;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
public interface CurrentProductFacilityLimitRepository extends JpaRepository<CurrentProductFacilityLimit, Long> {
|
||||
|
||||
List<CurrentProductFacilityLimit> findByCurrentProductId(Long currentProductId);
|
||||
|
||||
@Transactional
|
||||
void deleteByCurrentProductId(Long currentProductId);
|
||||
}
|
||||
+25
@@ -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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface CurrentProductRepository extends JpaRepository<CurrentProduct, Long>, JpaSpecificationExecutor<CurrentProduct> {
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.service;
|
||||
|
||||
import java.util.Collection;
|
||||
import org.apache.fineract.portfolio.savings.data.SavingsProductData;
|
||||
|
||||
public interface CurrentProductReadPlatformService {
|
||||
|
||||
Collection<SavingsProductData> retrieveAll();
|
||||
|
||||
Collection<SavingsProductData> retrieveAllForLookup();
|
||||
|
||||
SavingsProductData retrieveOne(Long productId);
|
||||
}
|
||||
+346
@@ -0,0 +1,346 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.service;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.accounting.common.AccountingEnumerations;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductDepositLimitKyc;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductDepositLimitKycRepository;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductFacilityConfig;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductFacilityConfigRepository;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductFacilityLimit;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductFacilityLimitRepository;
|
||||
import org.apache.fineract.portfolio.savings.data.SavingsProductData;
|
||||
import org.apache.fineract.portfolio.savings.exception.SavingsProductNotFoundException;
|
||||
import org.apache.fineract.portfolio.savings.service.SavingsEnumerations;
|
||||
import org.apache.fineract.portfolio.tax.data.TaxGroupData;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class CurrentProductReadPlatformServiceImpl implements CurrentProductReadPlatformService {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final CurrentProductFacilityConfigRepository facilityConfigRepository;
|
||||
private final CurrentProductFacilityLimitRepository facilityLimitRepository;
|
||||
private final CurrentProductDepositLimitKycRepository depositLimitKycRepository;
|
||||
|
||||
private final CurrentProductMapper currentProductRowMapper = new CurrentProductMapper();
|
||||
private final CurrentProductLookupMapper currentProductLookupsRowMapper = new CurrentProductLookupMapper();
|
||||
|
||||
private static final Gson GSON = new Gson();
|
||||
private static final Type OTHER_GL_MAPPINGS_TYPE = new TypeToken<Map<String, List<Map<String, Object>>>>() {}.getType();
|
||||
|
||||
@Override
|
||||
public Collection<SavingsProductData> retrieveAll() {
|
||||
this.context.authenticatedUser();
|
||||
final String sql = "select " + this.currentProductRowMapper.schema();
|
||||
return this.jdbcTemplate.query(sql, this.currentProductRowMapper); // NOSONAR
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SavingsProductData> retrieveAllForLookup() {
|
||||
final String sql = "select " + this.currentProductLookupsRowMapper.schema();
|
||||
return this.jdbcTemplate.query(sql, this.currentProductLookupsRowMapper); // NOSONAR
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingsProductData retrieveOne(final Long productId) {
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
final String sql = "select " + this.currentProductRowMapper.schema() + " where cp.id = ?";
|
||||
SavingsProductData product = this.jdbcTemplate.queryForObject(sql, this.currentProductRowMapper, // NOSONAR
|
||||
new Object[] { productId });
|
||||
|
||||
if (product != null) {
|
||||
// Fetch Facility Config
|
||||
CurrentProductFacilityConfig facilityConfig = facilityConfigRepository.findByCurrentProductId(productId);
|
||||
if (facilityConfig != null) {
|
||||
Map<String, Object> facilityConfigMap = new HashMap<>();
|
||||
facilityConfigMap.put("atmFacility", facilityConfig.getAtmFacility());
|
||||
facilityConfigMap.put("atmWithdrawalFacility", facilityConfig.getAtmWithdrawalFacility());
|
||||
facilityConfigMap.put("upiFacility", facilityConfig.getUpiFacility());
|
||||
facilityConfigMap.put("posTransactionsFacility", facilityConfig.getPosTransactionsFacility());
|
||||
facilityConfigMap.put("chequeBook", facilityConfig.getChequeBook());
|
||||
facilityConfigMap.put("impsFacility", facilityConfig.getImpsFacility());
|
||||
facilityConfigMap.put("smsAlerts", facilityConfig.getSmsAlerts());
|
||||
facilityConfigMap.put("bbpsFacility", facilityConfig.getBbpsFacility());
|
||||
facilityConfigMap.put("insuranceCover", facilityConfig.getInsuranceCover());
|
||||
facilityConfigMap.put("bepgFacility", facilityConfig.getBepgFacility());
|
||||
facilityConfigMap.put("neftFacility", facilityConfig.getNeftFacility());
|
||||
facilityConfigMap.put("rtgsFacility", facilityConfig.getRtgsFacility());
|
||||
facilityConfigMap.put("interBankTotalCapFacility", facilityConfig.getInterBankTotalCapFacility());
|
||||
facilityConfigMap.put("withdrawalFacility", facilityConfig.getWithdrawalFacility());
|
||||
facilityConfigMap.put("depositFacilityKyc", facilityConfig.getDepositFacilityKyc());
|
||||
facilityConfigMap.put("virtualDebitCard", facilityConfig.getVirtualDebitCard());
|
||||
product.setAccountFacilityConfig(facilityConfigMap);
|
||||
}
|
||||
|
||||
// Fetch Facility Limits
|
||||
List<CurrentProductFacilityLimit> facilityLimits = facilityLimitRepository.findByCurrentProductId(productId);
|
||||
if (facilityLimits != null && !facilityLimits.isEmpty()) {
|
||||
List<Map<String, Object>> limits = facilityLimits.stream().map(limit -> {
|
||||
Map<String, Object> limitMap = new HashMap<>();
|
||||
limitMap.put("limitType", limit.getLimitType());
|
||||
limitMap.put("generalLimit", limit.getGeneralLimit());
|
||||
limitMap.put("minorAccountLimit", limit.getMinorAccountLimit());
|
||||
limitMap.put("smallSavingLimit", limit.getSmallSavingLimit());
|
||||
return limitMap;
|
||||
}).toList();
|
||||
product.setAccountFacilityLimits(limits);
|
||||
}
|
||||
|
||||
// Fetch Deposit Limit KYC
|
||||
CurrentProductDepositLimitKyc depositLimitKyc = depositLimitKycRepository.findByCurrentProductId(productId);
|
||||
if (depositLimitKyc != null) {
|
||||
Map<String, Object> depositLimitKycMap = new HashMap<>();
|
||||
depositLimitKycMap.put("general", Map.of(
|
||||
"kycType", depositLimitKyc.getGeneralKycType() != null ? depositLimitKyc.getGeneralKycType() : "",
|
||||
"limit", depositLimitKyc.getGeneralLimit() != null ? depositLimitKyc.getGeneralLimit() : ""));
|
||||
depositLimitKycMap.put("minor", Map.of(
|
||||
"kycType", depositLimitKyc.getMinorKycType() != null ? depositLimitKyc.getMinorKycType() : "",
|
||||
"limit", depositLimitKyc.getMinorLimit() != null ? depositLimitKyc.getMinorLimit() : 0L));
|
||||
depositLimitKycMap.put("smallSaving", Map.of(
|
||||
"kycType", depositLimitKyc.getSmallSavingKycType() != null ? depositLimitKyc.getSmallSavingKycType() : "",
|
||||
"limit", depositLimitKyc.getSmallSavingLimit() != null ? depositLimitKyc.getSmallSavingLimit() : 0L));
|
||||
product.setDepositLimitKyc(depositLimitKycMap);
|
||||
}
|
||||
}
|
||||
|
||||
return product;
|
||||
} catch (final EmptyResultDataAccessException e) {
|
||||
throw new SavingsProductNotFoundException(productId, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class CurrentProductMapper implements RowMapper<SavingsProductData> {
|
||||
|
||||
private final String schemaSql;
|
||||
|
||||
CurrentProductMapper() {
|
||||
final StringBuilder sqlBuilder = new StringBuilder(1000);
|
||||
sqlBuilder.append("cp.id as id, cp.name as name, cp.short_name as shortName, cp.description as description, ");
|
||||
sqlBuilder.append(
|
||||
"cp.currency_code as currencyCode, cp.currency_digits as currencyDigits, cp.currency_multiplesof as inMultiplesOf, ");
|
||||
sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
|
||||
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
|
||||
sqlBuilder.append("cp.nominal_annual_interest_rate as nominalAnnualInterestRate, ");
|
||||
sqlBuilder.append("cp.interest_compounding_period_enum as compoundingInterestPeriodType, ");
|
||||
sqlBuilder.append("cp.interest_posting_period_enum as interestPostingPeriodType, ");
|
||||
sqlBuilder.append("cp.interest_calculation_type_enum as interestCalculationType, ");
|
||||
sqlBuilder.append("cp.interest_calculation_days_in_year_type_enum as interestCalculationDaysInYearType, ");
|
||||
sqlBuilder.append("cp.min_required_opening_balance as minRequiredOpeningBalance, ");
|
||||
sqlBuilder.append("cp.lockin_period_frequency as lockinPeriodFrequency,");
|
||||
sqlBuilder.append("cp.lockin_period_frequency_enum as lockinPeriodFrequencyType, ");
|
||||
sqlBuilder.append("cp.withdrawal_fee_for_transfer as withdrawalFeeForTransfers, ");
|
||||
sqlBuilder.append("cp.allow_overdraft as allowOverdraft, ");
|
||||
sqlBuilder.append("cp.overdraft_limit as overdraftLimit, ");
|
||||
sqlBuilder.append("cp.nominal_annual_interest_rate_overdraft as nominalAnnualInterestRateOverdraft, ");
|
||||
sqlBuilder.append("cp.min_overdraft_for_interest_calculation as minOverdraftForInterestCalculation, ");
|
||||
sqlBuilder.append("cp.min_required_balance as minRequiredBalance, ");
|
||||
sqlBuilder.append("cp.enforce_min_required_balance as enforceMinRequiredBalance, ");
|
||||
sqlBuilder.append("cp.max_allowed_lien_limit as maxAllowedLienLimit, ");
|
||||
sqlBuilder.append("cp.is_lien_allowed as lienAllowed, ");
|
||||
sqlBuilder.append("cp.min_balance_for_interest_calculation as minBalanceForInterestCalculation,");
|
||||
sqlBuilder.append("cp.accounting_type as accountingType, ");
|
||||
sqlBuilder.append("cp.withhold_tax as withHoldTax,");
|
||||
sqlBuilder.append("tg.id as taxGroupId, tg.name as taxGroupName, ");
|
||||
sqlBuilder.append("cp.is_dormancy_tracking_active as isDormancyTrackingActive,");
|
||||
sqlBuilder.append("cp.days_to_inactive as daysToInactive,");
|
||||
sqlBuilder.append("cp.days_to_dormancy as daysToDormancy,");
|
||||
sqlBuilder.append("cp.days_to_escheat as daysToEscheat, ");
|
||||
sqlBuilder.append("cp.other_gl_mappings as otherGlMappings, ");
|
||||
|
||||
// Enhanced fields
|
||||
sqlBuilder.append("cp.account_type as accountType, cp.customer_segment as customerSegment, cp.product_code as productCode, ");
|
||||
sqlBuilder.append("cp.effective_date as effectiveDate, cp.effective_to as effectiveTo, cp.end_date as endDate, ");
|
||||
sqlBuilder.append("cp.introducer_required as introducerRequired, cp.share_linking_enabled as shareLinkingEnabled, ");
|
||||
sqlBuilder.append("cp.nomination_facility as nominationFacility, cp.dormancy_alert as dormancyAlert, ");
|
||||
sqlBuilder.append("cp.interest_calculate_selector as interestCalculateSelector, cp.average_period as averagePeriod, ");
|
||||
sqlBuilder.append("cp.auto_post as autoPost, cp.frequency_fix_day as frequencyFixDay, cp.last_interest_date as lastInterestDate, ");
|
||||
sqlBuilder.append("cp.enable_lockin_period as enableLockinPeriod, ");
|
||||
sqlBuilder.append("cp.balance_frequency as balanceFrequency, ");
|
||||
sqlBuilder.append("cp.account_closed_zero_balance_in_day_closing as accountClosedZeroBalanceInDayClosing, ");
|
||||
sqlBuilder.append("cp.balance_swap_option as balanceSwapOption, cp.msme as msme, cp.auto_debit_facility as autoDebitFacility, ");
|
||||
sqlBuilder.append("cp.avg_balance_calc_period as avgBalanceCalcPeriod, cp.valid_for_period as validForPeriod, ");
|
||||
sqlBuilder.append("cp.od_account_closed_zero_balance_in_day_closing as odAccountClosedZeroBalanceInDayClosing ");
|
||||
|
||||
sqlBuilder.append("from m_current_product cp ");
|
||||
sqlBuilder.append("join m_currency curr on curr.code = cp.currency_code ");
|
||||
sqlBuilder.append("left join m_tax_group tg on tg.id = cp.tax_group_id ");
|
||||
|
||||
this.schemaSql = sqlBuilder.toString();
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
return this.schemaSql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingsProductData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long id = rs.getLong("id");
|
||||
final String name = rs.getString("name");
|
||||
final String shortName = rs.getString("shortName");
|
||||
final String description = rs.getString("description");
|
||||
|
||||
final String currencyCode = rs.getString("currencyCode");
|
||||
final String currencyName = rs.getString("currencyName");
|
||||
final String currencyNameCode = rs.getString("currencyNameCode");
|
||||
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
|
||||
final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");
|
||||
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
|
||||
final BigDecimal nominalAnnualInterestRate = rs.getBigDecimal("nominalAnnualInterestRate");
|
||||
|
||||
final Integer compoundingInterestPeriodTypeValue = JdbcSupport.getInteger(rs, "compoundingInterestPeriodType");
|
||||
final EnumOptionData compoundingInterestPeriodType = SavingsEnumerations
|
||||
.compoundingInterestPeriodType(compoundingInterestPeriodTypeValue);
|
||||
|
||||
final Integer interestPostingPeriodTypeValue = JdbcSupport.getInteger(rs, "interestPostingPeriodType");
|
||||
final EnumOptionData interestPostingPeriodType = SavingsEnumerations.interestPostingPeriodType(interestPostingPeriodTypeValue);
|
||||
|
||||
final Integer interestCalculationTypeValue = JdbcSupport.getInteger(rs, "interestCalculationType");
|
||||
final EnumOptionData interestCalculationType = SavingsEnumerations.interestCalculationType(interestCalculationTypeValue);
|
||||
|
||||
EnumOptionData interestCalculationDaysInYearType = null;
|
||||
final Integer interestCalculationDaysInYearTypeValue = JdbcSupport.getInteger(rs, "interestCalculationDaysInYearType");
|
||||
if (interestCalculationDaysInYearTypeValue != null) {
|
||||
interestCalculationDaysInYearType = SavingsEnumerations
|
||||
.interestCalculationDaysInYearType(interestCalculationDaysInYearTypeValue);
|
||||
}
|
||||
|
||||
final Integer accountingRuleId = JdbcSupport.getInteger(rs, "accountingType");
|
||||
final EnumOptionData accountingRuleType = AccountingEnumerations.accountingRuleType(accountingRuleId);
|
||||
|
||||
final BigDecimal minRequiredOpeningBalance = rs.getBigDecimal("minRequiredOpeningBalance");
|
||||
|
||||
final Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockinPeriodFrequency");
|
||||
EnumOptionData lockinPeriodFrequencyType = null;
|
||||
final Integer lockinPeriodFrequencyTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodFrequencyType");
|
||||
if (lockinPeriodFrequencyTypeValue != null) {
|
||||
lockinPeriodFrequencyType = SavingsEnumerations.lockinPeriodFrequencyType(lockinPeriodFrequencyTypeValue);
|
||||
}
|
||||
|
||||
final boolean withdrawalFeeForTransfers = rs.getBoolean("withdrawalFeeForTransfers");
|
||||
final boolean allowOverdraft = rs.getBoolean("allowOverdraft");
|
||||
final BigDecimal overdraftLimit = rs.getBigDecimal("overdraftLimit");
|
||||
final BigDecimal nominalAnnualInterestRateOverdraft = rs.getBigDecimal("nominalAnnualInterestRateOverdraft");
|
||||
final BigDecimal minOverdraftForInterestCalculation = rs.getBigDecimal("minOverdraftForInterestCalculation");
|
||||
|
||||
final BigDecimal minRequiredBalance = rs.getBigDecimal("minRequiredBalance");
|
||||
final boolean enforceMinRequiredBalance = rs.getBoolean("enforceMinRequiredBalance");
|
||||
final BigDecimal maxAllowedLienLimit = rs.getBigDecimal("maxAllowedLienLimit");
|
||||
final boolean lienAllowed = rs.getBoolean("lienAllowed");
|
||||
final BigDecimal minBalanceForInterestCalculation = rs.getBigDecimal("minBalanceForInterestCalculation");
|
||||
|
||||
final boolean withHoldTax = rs.getBoolean("withHoldTax");
|
||||
final Long taxGroupId = JdbcSupport.getLong(rs, "taxGroupId");
|
||||
final String taxGroupName = rs.getString("taxGroupName");
|
||||
TaxGroupData taxGroupData = null;
|
||||
if (taxGroupId != null) {
|
||||
taxGroupData = TaxGroupData.lookup(taxGroupId, taxGroupName);
|
||||
}
|
||||
|
||||
final Boolean isDormancyTrackingActive = rs.getBoolean("isDormancyTrackingActive");
|
||||
final Long daysToInactive = JdbcSupport.getLong(rs, "daysToInactive");
|
||||
final Long daysToDormancy = JdbcSupport.getLong(rs, "daysToDormancy");
|
||||
final Long daysToEscheat = JdbcSupport.getLong(rs, "daysToEscheat");
|
||||
final Map<String, List<Map<String, Object>>> otherGlMappings = parseOtherGlMappings(rs.getString("otherGlMappings"));
|
||||
|
||||
SavingsProductData productData = SavingsProductData.instance(id, name, shortName, description, currency,
|
||||
nominalAnnualInterestRate, compoundingInterestPeriodType, interestPostingPeriodType, interestCalculationType,
|
||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
|
||||
withdrawalFeeForTransfers, accountingRuleType, allowOverdraft, overdraftLimit, minRequiredBalance,
|
||||
enforceMinRequiredBalance, maxAllowedLienLimit, lienAllowed, minBalanceForInterestCalculation,
|
||||
nominalAnnualInterestRateOverdraft, minOverdraftForInterestCalculation, withHoldTax, taxGroupData, null, null, null,
|
||||
isDormancyTrackingActive, daysToInactive, daysToDormancy, daysToEscheat, null);
|
||||
productData.setOtherGlMappingsMap(otherGlMappings);
|
||||
|
||||
// Populate Enhanced Fields
|
||||
productData.setAccountType(rs.getString("accountType"));
|
||||
productData.setCustomerSegment(rs.getString("customerSegment"));
|
||||
productData.setProductCode(rs.getString("productCode"));
|
||||
productData.setEffectiveDate(JdbcSupport.getLocalDate(rs, "effectiveDate"));
|
||||
productData.setEffectiveTo(JdbcSupport.getLocalDate(rs, "effectiveTo"));
|
||||
productData.setEndDate(JdbcSupport.getLocalDate(rs, "endDate"));
|
||||
productData.setIntroducerRequired(rs.getBoolean("introducerRequired"));
|
||||
productData.setShareLinkingEnabled(rs.getBoolean("shareLinkingEnabled"));
|
||||
productData.setNominationFacility(rs.getBoolean("nominationFacility"));
|
||||
productData.setDormancyAlert(rs.getBoolean("dormancyAlert"));
|
||||
productData.setInterestCalculateSelector(JdbcSupport.getInteger(rs, "interestCalculateSelector"));
|
||||
productData.setAveragePeriod(rs.getString("averagePeriod"));
|
||||
productData.setAutoPost(rs.getBoolean("autoPost"));
|
||||
productData.setFrequencyFixDay(JdbcSupport.getInteger(rs, "frequencyFixDay"));
|
||||
productData.setLastInterestDate(JdbcSupport.getLocalDate(rs, "lastInterestDate"));
|
||||
productData.setEnableLockinPeriod(rs.getBoolean("enableLockinPeriod"));
|
||||
productData.setBalanceFrequency(rs.getString("balanceFrequency"));
|
||||
productData.setAccountClosedZeroBalanceInDayClosing(rs.getBoolean("accountClosedZeroBalanceInDayClosing"));
|
||||
productData.setBalanceSwapOption(rs.getBoolean("balanceSwapOption"));
|
||||
productData.setMsme(rs.getBoolean("msme"));
|
||||
productData.setAutoDebitFacility(rs.getBoolean("autoDebitFacility"));
|
||||
productData.setAvgBalanceCalcPeriod(rs.getString("avgBalanceCalcPeriod"));
|
||||
productData.setValidForPeriod(rs.getString("validForPeriod"));
|
||||
productData.setOdAccountClosedZeroBalanceInDayClosing(rs.getBoolean("odAccountClosedZeroBalanceInDayClosing"));
|
||||
|
||||
return productData;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class CurrentProductLookupMapper implements RowMapper<SavingsProductData> {
|
||||
|
||||
public String schema() {
|
||||
return " cp.id as id, cp.name as name from m_current_product cp";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingsProductData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
final Long id = rs.getLong("id");
|
||||
final String name = rs.getString("name");
|
||||
return SavingsProductData.lookup(id, name);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, List<Map<String, Object>>> parseOtherGlMappings(final String otherGlMappingsJson) {
|
||||
if (otherGlMappingsJson == null || otherGlMappingsJson.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
return GSON.fromJson(otherGlMappingsJson, OTHER_GL_MAPPINGS_TYPE);
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.service;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
|
||||
public interface CurrentProductWritePlatformService {
|
||||
|
||||
CommandProcessingResult create(JsonCommand command);
|
||||
|
||||
CommandProcessingResult update(Long productId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult delete(Long productId);
|
||||
}
|
||||
+267
@@ -0,0 +1,267 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.service;
|
||||
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accountingRuleParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.chargesParamName;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.taxGroupIdParamName;
|
||||
|
||||
import jakarta.persistence.PersistenceException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.service.ProductToGLAccountMappingWritePlatformService;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.portfolio.charge.domain.Charge;
|
||||
import org.apache.fineract.portfolio.currentproduct.data.CurrentProductDataValidator;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProduct;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductAssembler;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductDepositLimitKyc;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductDepositLimitKycRepository;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductFacilityConfig;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductFacilityConfigRepository;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductFacilityLimit;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductFacilityLimitRepository;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductRepository;
|
||||
import org.apache.fineract.portfolio.savings.DepositsApiConstants;
|
||||
import org.apache.fineract.portfolio.savings.DepositAccountType;
|
||||
import org.apache.fineract.portfolio.savings.exception.SavingsProductNotFoundException;
|
||||
import org.apache.fineract.portfolio.tax.domain.TaxGroup;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class CurrentProductWritePlatformServiceJpaRepositoryImpl implements CurrentProductWritePlatformService {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final CurrentProductRepository currentProductRepository;
|
||||
private final CurrentProductDataValidator fromApiJsonDataValidator;
|
||||
private final CurrentProductAssembler currentProductAssembler;
|
||||
private final ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService;
|
||||
private final CurrentProductFacilityConfigRepository facilityConfigRepository;
|
||||
private final CurrentProductFacilityLimitRepository facilityLimitRepository;
|
||||
private final CurrentProductDepositLimitKycRepository depositLimitKycRepository;
|
||||
|
||||
private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dae) {
|
||||
String msgCode = "error.msg." + DepositsApiConstants.CURRENT_PRODUCT_RESOURCE_NAME;
|
||||
String msg = "Unknown data integrity issue with current product.";
|
||||
String param = null;
|
||||
Object[] msgArgs;
|
||||
Throwable checkEx = realCause == null ? dae : realCause;
|
||||
if (checkEx.getMessage().contains("cp_unq_name")) {
|
||||
final String name = command.stringValueOfParameterNamed("name");
|
||||
msgCode += ".duplicate.name";
|
||||
msg = "Current product with name `" + name + "` already exists";
|
||||
param = "name";
|
||||
msgArgs = new Object[] { name, dae };
|
||||
} else if (checkEx.getMessage().contains("cp_unq_short_name")) {
|
||||
final String shortName = command.stringValueOfParameterNamed("shortName");
|
||||
msgCode += ".duplicate.short.name";
|
||||
msg = "Current product with short name `" + shortName + "` already exists";
|
||||
param = "shortName";
|
||||
msgArgs = new Object[] { shortName, dae };
|
||||
} else if (checkEx.getMessage().contains("cp_unq_product_code")) {
|
||||
final String productCode = command.stringValueOfParameterNamed("productCode");
|
||||
msgCode += ".duplicate.product.code";
|
||||
msg = "Current product with product code `" + productCode + "` already exists";
|
||||
param = "productCode";
|
||||
msgArgs = new Object[] { productCode, dae };
|
||||
} else {
|
||||
msgCode += ".unknown.data.integrity.issue";
|
||||
msg = "Unknown data integrity issue with current product. Details: " + checkEx.getMessage();
|
||||
msgArgs = new Object[] { dae };
|
||||
}
|
||||
log.error("Error occured.", dae);
|
||||
throw ErrorHandler.getMappable(dae, msgCode, msg, param, msgArgs);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult create(final JsonCommand command) {
|
||||
try {
|
||||
this.fromApiJsonDataValidator.validateForCreate(command.json());
|
||||
|
||||
final CurrentProduct product = this.currentProductAssembler.assemble(command);
|
||||
|
||||
final CurrentProductFacilityConfig facilityConfig =
|
||||
this.currentProductAssembler.assembleAccountFacilityConfig(command, product);
|
||||
final Set<CurrentProductFacilityLimit> facilityLimits =
|
||||
this.currentProductAssembler.assembleAccountFacilityLimits(command, product);
|
||||
final CurrentProductDepositLimitKyc depositLimitKyc =
|
||||
this.currentProductAssembler.assembleDepositLimitKyc(command, product);
|
||||
|
||||
this.currentProductRepository.saveAndFlush(product);
|
||||
|
||||
if (facilityConfig != null) {
|
||||
this.facilityConfigRepository.saveAndFlush(facilityConfig);
|
||||
}
|
||||
|
||||
if (!facilityLimits.isEmpty()) {
|
||||
this.facilityLimitRepository.saveAll(facilityLimits);
|
||||
}
|
||||
|
||||
if (depositLimitKyc != null) {
|
||||
this.depositLimitKycRepository.saveAndFlush(depositLimitKyc);
|
||||
}
|
||||
|
||||
this.accountMappingWritePlatformService.createSavingProductToGLAccountMapping(product.getId(), command,
|
||||
DepositAccountType.SAVINGS_DEPOSIT);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(product.getId()) //
|
||||
.build();
|
||||
} catch (final DataAccessException e) {
|
||||
handleDataIntegrityIssues(command, e.getMostSpecificCause(), e);
|
||||
return CommandProcessingResult.empty();
|
||||
} catch (final PersistenceException dve) {
|
||||
handleDataIntegrityIssues(command, ExceptionUtils.getRootCause(dve.getCause()), dve);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult update(final Long productId, final JsonCommand command) {
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
final CurrentProduct product = this.currentProductRepository.findById(productId)
|
||||
.orElseThrow(() -> new SavingsProductNotFoundException(productId));
|
||||
|
||||
this.fromApiJsonDataValidator.validateForUpdate(command.json(), product);
|
||||
|
||||
final Map<String, Object> changes = product.update(command);
|
||||
|
||||
if (changes.containsKey(chargesParamName)) {
|
||||
final Set<Charge> charges = this.currentProductAssembler.assembleListOfCurrentProductCharges(command,
|
||||
product.currency().getCode());
|
||||
final boolean updated = product.update(charges);
|
||||
if (!updated) {
|
||||
changes.remove(chargesParamName);
|
||||
}
|
||||
}
|
||||
|
||||
if (changes.containsKey(taxGroupIdParamName)) {
|
||||
final TaxGroup taxGroup = this.currentProductAssembler.assembleTaxGroup(command);
|
||||
product.setTaxGroup(taxGroup);
|
||||
if (product.withHoldTax() && product.getTaxGroup() == null) {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(DepositsApiConstants.CURRENT_PRODUCT_RESOURCE_NAME);
|
||||
final Long taxGroupId = null;
|
||||
baseDataValidator.reset().parameter(taxGroupIdParamName).value(taxGroupId).notBlank();
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
// Update facility config
|
||||
final CurrentProductFacilityConfig existingFacilityConfig = product.getFacilityConfig();
|
||||
final CurrentProductFacilityConfig newFacilityConfig =
|
||||
this.currentProductAssembler.assembleAccountFacilityConfig(command, product);
|
||||
|
||||
if (newFacilityConfig != null) {
|
||||
if (existingFacilityConfig != null) {
|
||||
existingFacilityConfig.updateFrom(newFacilityConfig);
|
||||
this.facilityConfigRepository.saveAndFlush(existingFacilityConfig);
|
||||
} else {
|
||||
this.facilityConfigRepository.saveAndFlush(newFacilityConfig);
|
||||
}
|
||||
} else if (existingFacilityConfig != null) {
|
||||
this.facilityConfigRepository.delete(existingFacilityConfig);
|
||||
}
|
||||
|
||||
// Update facility limits (delete old, insert new)
|
||||
final Set<CurrentProductFacilityLimit> newFacilityLimits =
|
||||
this.currentProductAssembler.assembleAccountFacilityLimits(command, product);
|
||||
|
||||
if (!newFacilityLimits.isEmpty() || command.hasParameter("accountFacilityLimits")) {
|
||||
if (product.getFacilityLimits() != null && !product.getFacilityLimits().isEmpty()) {
|
||||
this.facilityLimitRepository.deleteAll(product.getFacilityLimits());
|
||||
product.getFacilityLimits().clear();
|
||||
}
|
||||
if (!newFacilityLimits.isEmpty()) {
|
||||
this.facilityLimitRepository.saveAll(newFacilityLimits);
|
||||
product.setFacilityLimits(newFacilityLimits);
|
||||
}
|
||||
}
|
||||
|
||||
// Update deposit limit KYC
|
||||
final CurrentProductDepositLimitKyc existingDepositLimitKyc = product.getDepositLimitKyc();
|
||||
final CurrentProductDepositLimitKyc newDepositLimitKyc =
|
||||
this.currentProductAssembler.assembleDepositLimitKyc(command, product);
|
||||
|
||||
if (newDepositLimitKyc != null) {
|
||||
if (existingDepositLimitKyc != null) {
|
||||
existingDepositLimitKyc.updateFrom(newDepositLimitKyc);
|
||||
this.depositLimitKycRepository.saveAndFlush(existingDepositLimitKyc);
|
||||
} else {
|
||||
this.depositLimitKycRepository.saveAndFlush(newDepositLimitKyc);
|
||||
}
|
||||
} else if (existingDepositLimitKyc != null) {
|
||||
this.depositLimitKycRepository.delete(existingDepositLimitKyc);
|
||||
}
|
||||
|
||||
// accounting related changes
|
||||
final boolean accountingTypeChanged = changes.containsKey(accountingRuleParamName);
|
||||
final Map<String, Object> accountingMappingChanges = this.accountMappingWritePlatformService
|
||||
.updateSavingsProductToGLAccountMapping(product.getId(), command, accountingTypeChanged, product.getAccountingType(),
|
||||
DepositAccountType.SAVINGS_DEPOSIT);
|
||||
changes.putAll(accountingMappingChanges);
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
this.currentProductRepository.saveAndFlush(product);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(product.getId()) //
|
||||
.with(changes).build();
|
||||
} catch (final DataAccessException e) {
|
||||
handleDataIntegrityIssues(command, e.getMostSpecificCause(), e);
|
||||
return CommandProcessingResult.empty();
|
||||
} catch (final PersistenceException dve) {
|
||||
handleDataIntegrityIssues(command, ExceptionUtils.getRootCause(dve.getCause()), dve);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult delete(final Long productId) {
|
||||
this.context.authenticatedUser();
|
||||
final CurrentProduct product = this.currentProductRepository.findById(productId)
|
||||
.orElseThrow(() -> new SavingsProductNotFoundException(productId));
|
||||
|
||||
this.currentProductRepository.delete(product);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(product.getId()) //
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.currentproduct.starter;
|
||||
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.service.ProductToGLAccountMappingWritePlatformService;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.portfolio.currentproduct.data.CurrentProductDataValidator;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductAssembler;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductDepositLimitKycRepository;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductFacilityConfigRepository;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductFacilityLimitRepository;
|
||||
import org.apache.fineract.portfolio.currentproduct.domain.CurrentProductRepository;
|
||||
import org.apache.fineract.portfolio.currentproduct.service.CurrentProductReadPlatformService;
|
||||
import org.apache.fineract.portfolio.currentproduct.service.CurrentProductReadPlatformServiceImpl;
|
||||
import org.apache.fineract.portfolio.currentproduct.service.CurrentProductWritePlatformService;
|
||||
import org.apache.fineract.portfolio.currentproduct.service.CurrentProductWritePlatformServiceJpaRepositoryImpl;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
@Configuration
|
||||
public class CurrentProductConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(CurrentProductReadPlatformService.class)
|
||||
public CurrentProductReadPlatformService currentProductReadPlatformService(PlatformSecurityContext context,
|
||||
JdbcTemplate jdbcTemplate, CurrentProductFacilityConfigRepository currentFacilityConfigRepository,
|
||||
CurrentProductFacilityLimitRepository currentFacilityLimitRepository,
|
||||
CurrentProductDepositLimitKycRepository currentDepositLimitKycRepository) {
|
||||
return new CurrentProductReadPlatformServiceImpl(context, jdbcTemplate, currentFacilityConfigRepository,
|
||||
currentFacilityLimitRepository, currentDepositLimitKycRepository);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(CurrentProductWritePlatformService.class)
|
||||
public CurrentProductWritePlatformService currentProductWritePlatformService(PlatformSecurityContext context,
|
||||
CurrentProductRepository currentProductRepository, CurrentProductDataValidator currentProductDataValidator,
|
||||
CurrentProductAssembler currentProductAssembler,
|
||||
ProductToGLAccountMappingWritePlatformService accountMappingWritePlatformService,
|
||||
CurrentProductFacilityConfigRepository currentFacilityConfigRepository,
|
||||
CurrentProductFacilityLimitRepository currentFacilityLimitRepository,
|
||||
CurrentProductDepositLimitKycRepository currentDepositLimitKycRepository) {
|
||||
return new CurrentProductWritePlatformServiceJpaRepositoryImpl(context, currentProductRepository, currentProductDataValidator,
|
||||
currentProductAssembler, accountMappingWritePlatformService, currentFacilityConfigRepository,
|
||||
currentFacilityLimitRepository, currentDepositLimitKycRepository);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user