From ce255916dfa3697f8f9c77f619c927992a901cb8 Mon Sep 17 00:00:00 2001 From: Adam Saghy Date: Fri, 1 Mar 2024 14:39:44 +0100 Subject: [PATCH] FINERACT-1960: Fix savings product validation --- .../data/DepositProductDataValidator.java | 2 +- ...SavingsProductAccountingDataValidator.java | 152 +++++++++++------- .../data/SavingsProductDataValidator.java | 11 +- 3 files changed, 99 insertions(+), 66 deletions(-) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/DepositProductDataValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/DepositProductDataValidator.java index a30f97b63..e3a740109 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/DepositProductDataValidator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/DepositProductDataValidator.java @@ -302,7 +302,7 @@ public class DepositProductDataValidator { if (AccountingValidations.isCashBasedAccounting(accountingRuleType) || AccountingValidations.isAccrualPeriodicBasedAccounting(accountingRuleType)) { savingsProductAccountingDataValidator.evaluateProductAccountingData(accountingRuleType, isDormancyActive, element, - baseDataValidator, accountType); + baseDataValidator, accountType, true); } validateTaxWithHoldingParams(baseDataValidator, element, true); diff --git a/fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductAccountingDataValidator.java b/fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductAccountingDataValidator.java index 1e527e758..809c69456 100644 --- a/fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductAccountingDataValidator.java +++ b/fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductAccountingDataValidator.java @@ -36,82 +36,112 @@ public class SavingsProductAccountingDataValidator { private final FromJsonHelper fromApiJsonHelper; public void evaluateProductAccountingData(final Integer accountingRuleType, final boolean isDormancyActive, final JsonElement element, - DataValidatorBuilder baseDataValidator, final DepositAccountType accountType) { + DataValidatorBuilder baseDataValidator, final DepositAccountType accountType, boolean ignoreExistenceValidation) { // GL Accounts for Cash or Accrual Periodic if (AccountingValidations.isCashBasedAccounting(accountingRuleType) || AccountingValidations.isAccrualPeriodicBasedAccounting(accountingRuleType)) { - final Long savingsControlAccountId = fromApiJsonHelper - .extractLongNamed(SavingProductAccountingParams.SAVINGS_CONTROL.getValue(), element); - baseDataValidator.reset().parameter(SavingProductAccountingParams.SAVINGS_CONTROL.getValue()).value(savingsControlAccountId) - .notNull().integerGreaterThanZero(); - - final Long savingsReferenceAccountId = fromApiJsonHelper - .extractLongNamed(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(), element); - baseDataValidator.reset().parameter(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue()).value(savingsReferenceAccountId) - .notNull().integerGreaterThanZero(); - - final Long transfersInSuspenseAccountId = fromApiJsonHelper - .extractLongNamed(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(), element); - baseDataValidator.reset().parameter(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue()) - .value(transfersInSuspenseAccountId).notNull().integerGreaterThanZero(); - - final Long interestOnSavingsAccountId = fromApiJsonHelper - .extractLongNamed(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(), element); - baseDataValidator.reset().parameter(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue()) - .value(interestOnSavingsAccountId).notNull().integerGreaterThanZero(); - - final Long incomeFromFeeId = fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_FEES.getValue(), - element); - baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_FEES.getValue()).value(incomeFromFeeId).notNull() - .integerGreaterThanZero(); - - final Long incomeFromPenaltyId = fromApiJsonHelper - .extractLongNamed(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(), element); - baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue()).value(incomeFromPenaltyId) - .notNull().integerGreaterThanZero(); - - if (!accountType.equals(DepositAccountType.RECURRING_DEPOSIT) && !accountType.equals(DepositAccountType.FIXED_DEPOSIT)) { - final Long overdraftControlAccountId = fromApiJsonHelper - .extractLongNamed(SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), element); - baseDataValidator.reset().parameter(SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue()) - .value(overdraftControlAccountId).notNull().integerGreaterThanZero(); - - final Long incomeFromInterest = fromApiJsonHelper - .extractLongNamed(SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue(), element); - baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue()).value(incomeFromInterest) + if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.SAVINGS_CONTROL.getValue(), element) + || ignoreExistenceValidation) { + final Long savingsControlAccountId = fromApiJsonHelper + .extractLongNamed(SavingProductAccountingParams.SAVINGS_CONTROL.getValue(), element); + baseDataValidator.reset().parameter(SavingProductAccountingParams.SAVINGS_CONTROL.getValue()).value(savingsControlAccountId) .notNull().integerGreaterThanZero(); + } - final Long writtenoff = fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(), + if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(), element) + || ignoreExistenceValidation) { + final Long savingsReferenceAccountId = fromApiJsonHelper + .extractLongNamed(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(), element); + baseDataValidator.reset().parameter(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue()) + .value(savingsReferenceAccountId).notNull().integerGreaterThanZero(); + } + if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(), element) + || ignoreExistenceValidation) { + final Long transfersInSuspenseAccountId = fromApiJsonHelper + .extractLongNamed(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(), element); + baseDataValidator.reset().parameter(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue()) + .value(transfersInSuspenseAccountId).notNull().integerGreaterThanZero(); + } + if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(), element) + || ignoreExistenceValidation) { + final Long interestOnSavingsAccountId = fromApiJsonHelper + .extractLongNamed(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(), element); + baseDataValidator.reset().parameter(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue()) + .value(interestOnSavingsAccountId).notNull().integerGreaterThanZero(); + } + if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.INCOME_FROM_FEES.getValue(), element) + || ignoreExistenceValidation) { + final Long incomeFromFeeId = fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_FEES.getValue(), element); - baseDataValidator.reset().parameter(SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue()).value(writtenoff).notNull() - .integerGreaterThanZero(); + baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_FEES.getValue()).value(incomeFromFeeId) + .notNull().integerGreaterThanZero(); + } + if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(), element) + || ignoreExistenceValidation) { + final Long incomeFromPenaltyId = fromApiJsonHelper + .extractLongNamed(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(), element); + baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue()) + .value(incomeFromPenaltyId).notNull().integerGreaterThanZero(); + } + if (!accountType.equals(DepositAccountType.RECURRING_DEPOSIT) && !accountType.equals(DepositAccountType.FIXED_DEPOSIT)) { + if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), element) + || ignoreExistenceValidation) { + final Long overdraftControlAccountId = fromApiJsonHelper + .extractLongNamed(SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), element); + baseDataValidator.reset().parameter(SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue()) + .value(overdraftControlAccountId).notNull().integerGreaterThanZero(); + } + if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue(), element) + || ignoreExistenceValidation) { + final Long incomeFromInterest = fromApiJsonHelper + .extractLongNamed(SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue(), element); + baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue()) + .value(incomeFromInterest).notNull().integerGreaterThanZero(); + } + if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(), element) + || ignoreExistenceValidation) { + final Long writtenoff = fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(), + element); + baseDataValidator.reset().parameter(SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue()).value(writtenoff) + .notNull().integerGreaterThanZero(); + } } if (isDormancyActive) { - final Long escheatLiabilityAccountId = fromApiJsonHelper - .extractLongNamed(SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue(), element); - baseDataValidator.reset().parameter(SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue()) - .value(escheatLiabilityAccountId).notNull().integerGreaterThanZero(); + if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue(), element) + || ignoreExistenceValidation) { + final Long escheatLiabilityAccountId = fromApiJsonHelper + .extractLongNamed(SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue(), element); + baseDataValidator.reset().parameter(SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue()) + .value(escheatLiabilityAccountId).notNull().integerGreaterThanZero(); + } } } // GL Accounts for Accrual Period only if (AccountingValidations.isAccrualPeriodicBasedAccounting(accountingRuleType)) { - final Long feeReceivableAccountId = fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.FEES_RECEIVABLE.getValue(), - element); - baseDataValidator.reset().parameter(SavingProductAccountingParams.FEES_RECEIVABLE.getValue()).value(feeReceivableAccountId) - .notNull().integerGreaterThanZero(); - - final Long penaltyReceivableAccountId = fromApiJsonHelper - .extractLongNamed(SavingProductAccountingParams.PENALTIES_RECEIVABLE.getValue(), element); - baseDataValidator.reset().parameter(SavingProductAccountingParams.PENALTIES_RECEIVABLE.getValue()) - .value(penaltyReceivableAccountId).notNull().integerGreaterThanZero(); - - final Long interestPayableAccountId = fromApiJsonHelper - .extractLongNamed(SavingProductAccountingParams.INTEREST_PAYABLE.getValue(), element); - baseDataValidator.reset().parameter(SavingProductAccountingParams.INTEREST_PAYABLE.getValue()).value(interestPayableAccountId) - .notNull().integerGreaterThanZero(); + if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.FEES_RECEIVABLE.getValue(), element) + || ignoreExistenceValidation) { + final Long feeReceivableAccountId = fromApiJsonHelper + .extractLongNamed(SavingProductAccountingParams.FEES_RECEIVABLE.getValue(), element); + baseDataValidator.reset().parameter(SavingProductAccountingParams.FEES_RECEIVABLE.getValue()).value(feeReceivableAccountId) + .notNull().integerGreaterThanZero(); + } + if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.PENALTIES_RECEIVABLE.getValue(), element) + || ignoreExistenceValidation) { + final Long penaltyReceivableAccountId = fromApiJsonHelper + .extractLongNamed(SavingProductAccountingParams.PENALTIES_RECEIVABLE.getValue(), element); + baseDataValidator.reset().parameter(SavingProductAccountingParams.PENALTIES_RECEIVABLE.getValue()) + .value(penaltyReceivableAccountId).notNull().integerGreaterThanZero(); + } + if (fromApiJsonHelper.parameterExists(SavingProductAccountingParams.INTEREST_PAYABLE.getValue(), element) + || ignoreExistenceValidation) { + final Long interestPayableAccountId = fromApiJsonHelper + .extractLongNamed(SavingProductAccountingParams.INTEREST_PAYABLE.getValue(), element); + baseDataValidator.reset().parameter(SavingProductAccountingParams.INTEREST_PAYABLE.getValue()) + .value(interestPayableAccountId).notNull().integerGreaterThanZero(); + } } validatePaymentChannelFundSourceMappings(baseDataValidator, element); diff --git a/fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductDataValidator.java b/fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductDataValidator.java index bac911472..87685317d 100644 --- a/fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductDataValidator.java +++ b/fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsProductDataValidator.java @@ -259,7 +259,7 @@ public class SavingsProductDataValidator { if (AccountingValidations.isCashBasedAccounting(accountingRuleType) || AccountingValidations.isAccrualPeriodicBasedAccounting(accountingRuleType)) { savingsProductAccountingDataValidator.evaluateProductAccountingData(accountingRuleType, isDormancyActive, element, - baseDataValidator, DepositAccountType.SAVINGS_DEPOSIT); + baseDataValidator, DepositAccountType.SAVINGS_DEPOSIT, true); } validateOverdraftParams(baseDataValidator, element); @@ -384,8 +384,11 @@ public class SavingsProductDataValidator { } // accounting related data validation - final Integer accountingRuleType = this.fromApiJsonHelper.extractIntegerNamed("accountingRule", element, Locale.getDefault()); - baseDataValidator.reset().parameter("accountingRule").value(accountingRuleType).notNull().inMinMaxRange(1, 3); + 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); + } // dormancy final Boolean isDormancyActive = this.fromApiJsonHelper.parameterExists(isDormancyTrackingActiveParamName, element) @@ -395,7 +398,7 @@ public class SavingsProductDataValidator { if (AccountingValidations.isCashBasedAccounting(accountingRuleType) || AccountingValidations.isAccrualPeriodicBasedAccounting(accountingRuleType)) { savingsProductAccountingDataValidator.evaluateProductAccountingData(accountingRuleType, isDormancyActive, element, - baseDataValidator, DepositAccountType.SAVINGS_DEPOSIT); + baseDataValidator, DepositAccountType.SAVINGS_DEPOSIT, false); } if (null != isDormancyActive && isDormancyActive) {