feat(deposits): allow several FD/RD accounts on the same product for one client

A client may now open any number of Fixed Deposit and Recurring Deposit accounts on
the same product, even while an earlier one is still active. The one-active-account-
per-product check is removed from submitFDApplication and submitRDApplication only;
the same rule on plain Savings and Current accounts is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-16 12:30:44 +05:30
co-authored by Claude Opus 5.5
parent 6be32272c1
commit 8ba0420398
@@ -48,7 +48,6 @@ import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.event.business.domain.deposit.FixedDepositAccountCreateBusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.deposit.RecurringDepositAccountCreateBusinessEvent;
@@ -184,16 +183,8 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
final FixedDepositAccount account = (FixedDepositAccount) this.depositAccountAssembler.assembleFrom(command, submittedBy,
DepositAccountType.FIXED_DEPOSIT);
if (account.getClient() != null && account.productId() != null) {
long existingCount = this.savingAccountRepository.countActiveAccountsByClientAndProduct(
account.getClient().getId(), account.productId());
if (existingCount > 0) {
throw new PlatformDataIntegrityException(
"error.msg.savings.account.duplicate.product.for.client",
"Client already has an active Fixed Deposit account with the same product.",
"productId", account.productId());
}
}
// A client may hold any number of Fixed Deposits on the same product, even while an earlier one is
// still active, so there is deliberately no one-active-account-per-product check here.
final MathContext mc = MathContext.DECIMAL64;
final boolean isPreMatureClosure = false;
@@ -269,16 +260,8 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
final RecurringDepositAccount account = (RecurringDepositAccount) this.depositAccountAssembler.assembleFrom(command,
submittedBy, DepositAccountType.RECURRING_DEPOSIT);
if (account.getClient() != null && account.productId() != null) {
long existingCount = this.savingAccountRepository.countActiveAccountsByClientAndProduct(
account.getClient().getId(), account.productId());
if (existingCount > 0) {
throw new PlatformDataIntegrityException(
"error.msg.savings.account.duplicate.product.for.client",
"Client already has an active Recurring Deposit account with the same product.",
"productId", account.productId());
}
}
// A client may hold any number of Recurring Deposits on the same product, even while an earlier one
// is still active, so there is deliberately no one-active-account-per-product check here.
this.savingsAccountAssembler.applyCbsFields(command, command.parsedJson(), account);