saving , current and RD account code update

This commit is contained in:
Nitesh Yadav
2026-04-23 11:20:35 +05:30
26 changed files with 43076 additions and 44411 deletions
@@ -216,8 +216,9 @@ public class DepositProductDataValidator {
validateRecurringDepositUpdate(element, baseDataValidator);
// RD products now use the CBS base chart as a read-only template, so
// product updates no longer require a charts payload.
if (!hasRdSlabsForUpdate) {
validateChartsData(element, baseDataValidator);
validateDepositAmountForUpdate(element, baseDataValidator);
}
@@ -140,7 +140,7 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
final Collection<EnumOptionData> withdrawalFeeTypeOptions = this.dropdownReadPlatformService.retrievewithdrawalFeeTypeOptions();
final Collection<SavingsAccountTransactionData> transactions = null;
final Collection<ChargeData> productCharges = this.chargeReadPlatformService.retrieveSavingsProductCharges(productId);
final Collection<ChargeData> productCharges = this.chargeReadPlatformService.retrieveCurrentProductCharges(productId);
final Collection<SavingsAccountChargeData> charges = fromChargesToSavingsCharges(productCharges);
final boolean feeChargesOnly = false;
@@ -170,6 +170,44 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions,
charges, chargeOptions);
// Re-apply CBS fields from full product data (withTemplateOptions creates a new object and loses setter fields)
final SavingsProductData productData = this.currentProductReadPlatformService.retrieveOne(productId);
if (productData != null) {
// Feature flags
template.setDormancyAlert(productData.getDormancyAlert() != null && productData.getDormancyAlert());
template.setBalanceSwapOption(productData.getBalanceSwapOption() != null && productData.getBalanceSwapOption());
template.setMsme(productData.getMsme() != null && productData.getMsme());
template.setNominationFacility(productData.getNominationFacility() != null && productData.getNominationFacility());
template.setAutoDebitFacility(productData.getAutoDebitFacility() != null && productData.getAutoDebitFacility());
template.setAutoPost(productData.getAutoPost() != null && productData.getAutoPost());
template.setFrequencyFixDay(productData.getFrequencyFixDay());
template.setLastInterestDate(productData.getLastInterestDate());
template.setInterestCalculateSelector(productData.getInterestCalculateSelector());
template.setAveragePeriod(productData.getAveragePeriod());
template.setAccountClosedZeroBalanceInDayClosing(
productData.getAccountClosedZeroBalanceInDayClosing() != null && productData.getAccountClosedZeroBalanceInDayClosing());
// Facility data
template.setAccountFacilityConfig(productData.getAccountFacilityConfig());
template.setAccountFacilityLimits(productData.getAccountFacilityLimits());
template.setDepositLimitKyc(productData.getDepositLimitKyc());
// Classification fields
template.setAccountType(productData.getAccountType());
template.setCustomerSegment(productData.getCustomerSegment());
template.setProductCode(productData.getProductCode());
template.setEffectiveDate(productData.getEffectiveDate());
template.setEffectiveTo(productData.getEffectiveTo());
template.setEndDate(productData.getEndDate());
template.setIntroducerRequired(productData.getIntroducerRequired());
template.setShareLinkingEnabled(productData.getShareLinkingEnabled());
// Settings fields
template.setEnableLockinPeriod(productData.getEnableLockinPeriod());
template.setBalanceFrequency(productData.getBalanceFrequency());
template.setAvgBalanceCalcPeriod(productData.getAvgBalanceCalcPeriod());
template.setValidForPeriod(productData.getValidForPeriod());
template.setOdAccountClosedZeroBalanceInDayClosing(
productData.getOdAccountClosedZeroBalanceInDayClosing() != null && productData.getOdAccountClosedZeroBalanceInDayClosing());
}
} else {
String clientName = null;
@@ -247,7 +285,22 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
sqlBuilder.append("cp.min_required_balance as minRequiredBalance, ");
sqlBuilder.append("cp.enforce_min_required_balance as enforceMinRequiredBalance, ");
sqlBuilder.append("0 as maxAllowedLienLimit, ");
sqlBuilder.append("0 as lienAllowed ");
sqlBuilder.append("0 as lienAllowed, ");
sqlBuilder.append("cp.dormancy_alert as dormancyAlert, ");
sqlBuilder.append("cp.balance_swap_option as balanceSwapOption, ");
sqlBuilder.append("cp.msme as msme, ");
sqlBuilder.append("cp.nomination_facility as nominationFacility, ");
sqlBuilder.append("cp.auto_debit_facility as autoDebitFacility, ");
sqlBuilder.append("cp.auto_post as autoPost, ");
sqlBuilder.append("cp.frequency_fix_day as frequencyFixDay, ");
sqlBuilder.append("cp.last_interest_date as lastInterestDate, ");
sqlBuilder.append("cp.interest_calculate_selector as interestCalculateSelector, ");
sqlBuilder.append("cp.average_period as averagePeriod, ");
sqlBuilder.append("cp.account_closed_zero_balance_in_day_closing as accountClosedZeroBalanceInDayClosing, ");
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("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 ");
@@ -346,14 +399,26 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
final SavingsAccountSubStatusEnumData subStatus = null;
final String reasonForBlock = null;
final LocalDate lastActiveTransactionDate = null;
final boolean isDormancyTrackingActive = false;
final Integer daysToInactive = null;
final Integer daysToDormancy = null;
final Integer daysToEscheat = null;
final boolean isDormancyTrackingActive = rs.getBoolean("isDormancyTrackingActive");
final Integer daysToInactive = JdbcSupport.getInteger(rs, "daysToInactive");
final Integer daysToDormancy = JdbcSupport.getInteger(rs, "daysToDormancy");
final Integer daysToEscheat = JdbcSupport.getInteger(rs, "daysToEscheat");
final boolean dormancyAlert = rs.getBoolean("dormancyAlert");
final boolean balanceSwapOption = rs.getBoolean("balanceSwapOption");
final boolean msme = rs.getBoolean("msme");
final boolean nominationFacility = rs.getBoolean("nominationFacility");
final boolean autoDebitFacility = rs.getBoolean("autoDebitFacility");
final boolean autoPost = rs.getBoolean("autoPost");
final Integer frequencyFixDay = JdbcSupport.getInteger(rs, "frequencyFixDay");
final LocalDate lastInterestDate = JdbcSupport.getLocalDate(rs, "lastInterestDate");
final Integer interestCalculateSelector = JdbcSupport.getInteger(rs, "interestCalculateSelector");
final String averagePeriod = rs.getString("averagePeriod");
final boolean accountClosedZeroBalanceInDayClosing = rs.getBoolean("accountClosedZeroBalanceInDayClosing");
final SavingsAccountApplicationTimelineData timeline = SavingsAccountApplicationTimelineData.templateDefault();
final EnumOptionData depositType = null;
return SavingsAccountData.instance(null, null, depositType, null, groupId, groupName, clientId, clientName, productId,
final SavingsAccountData accountData = SavingsAccountData.instance(null, null, depositType, null, groupId, groupName, clientId, clientName, productId,
productName, fieldOfficerId, fieldOfficerName, status, subStatus, reasonForBlock, timeline, currency,
nominalAnnualIterestRate, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
@@ -361,6 +426,19 @@ public class CurrentAccountTemplateReadPlatformServiceImpl implements CurrentAcc
maxAllowedLienLimit, lienAllowed, minBalanceForInterestCalculation, onHoldFunds, nominalAnnualInterestRateOverdraft,
minOverdraftForInterestCalculation, withHoldTax, taxGroupData, lastActiveTransactionDate, isDormancyTrackingActive,
daysToInactive, daysToDormancy, daysToEscheat, savingsAmountOnHold);
accountData.setDormancyAlert(dormancyAlert);
accountData.setBalanceSwapOption(balanceSwapOption);
accountData.setMsme(msme);
accountData.setNominationFacility(nominationFacility);
accountData.setAutoDebitFacility(autoDebitFacility);
accountData.setAutoPost(autoPost);
accountData.setFrequencyFixDay(frequencyFixDay);
accountData.setLastInterestDate(lastInterestDate);
accountData.setInterestCalculateSelector(interestCalculateSelector);
accountData.setAveragePeriod(averagePeriod);
accountData.setAccountClosedZeroBalanceInDayClosing(accountClosedZeroBalanceInDayClosing);
return accountData;
}
}
@@ -382,7 +382,9 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
// retrieve chart Slabs
final InterestRateChartData productChartData = this.productChartReadPlatformService.retrieveActiveChartWithTemplate(productId);
final DepositAccountInterestRateChartData accountChart = DepositAccountInterestRateChartData.from(productChartData);
final DepositAccountInterestRateChartData accountChart = (productChartData != null)
? DepositAccountInterestRateChartData.from(productChartData)
: null;
if (depositAccountType.isFixedDeposit()) {
@@ -394,13 +396,17 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
template = FixedDepositAccountData.withInterestChart((FixedDepositAccountData) template, accountChart);
} else if (depositAccountType.isRecurringDeposit()) {
template = RecurringDepositAccountData.withTemplateOptions((RecurringDepositAccountData) template, productOptions,
// Save CBS fields from mapper result before factory methods create new objects
final RecurringDepositAccountData rdTemplateWithCbs = (RecurringDepositAccountData) template;
template = RecurringDepositAccountData.withTemplateOptions(rdTemplateWithCbs, productOptions,
fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, transactions, charges, chargeOptions, preClosurePenalInterestOnTypeOptions,
periodFrequencyTypeOptions);
template = RecurringDepositAccountData.withInterestChartAndRecurringDetails((RecurringDepositAccountData) template,
accountChart, null, null);
// Re-apply CBS product fields lost during factory method object creation
((RecurringDepositAccountData) template).copyCbsFieldsFrom(rdTemplateWithCbs);
}
@@ -1473,10 +1479,33 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
sqlBuilder.append("dptp.min_deposit_term_type_enum as minDepositTermTypeId, ");
sqlBuilder.append("dptp.max_deposit_term_type_enum as maxDepositTermTypeId, ");
sqlBuilder.append("dptp.in_multiples_of_deposit_term as inMultiplesOfDepositTerm, ");
sqlBuilder.append("dptp.in_multiples_of_deposit_term_type_enum as inMultiplesOfDepositTermTypeId ");
sqlBuilder.append("dptp.in_multiples_of_deposit_term_type_enum as inMultiplesOfDepositTermTypeId, ");
sqlBuilder.append("sa.account_type as accountType, sa.customer_segment as customerSegment, ");
sqlBuilder.append("sa.product_code as productCode, ");
sqlBuilder.append("sa.effective_date as effectiveDate, sa.effective_to as effectiveTo, sa.end_date as endDate, ");
sqlBuilder.append("sa.introducer_required as introducerRequired, sa.share_linking_enabled as shareLinkingEnabled, ");
sqlBuilder.append("sa.nomination_facility as nominationFacility, sa.dormancy_alert as dormancyAlert, ");
sqlBuilder.append("sa.interest_calculate_selector as interestCalculateSelector, ");
sqlBuilder.append("icv.code_value as interestCalculationTypeName, ");
sqlBuilder.append("sa.average_period as averagePeriod, ");
sqlBuilder.append("sa.auto_post as autoPost, sa.frequency_fix_day as frequencyFixDay, ");
sqlBuilder.append("sa.last_interest_date as lastInterestDate, sa.enable_lockin_period as enableLockinPeriod, ");
sqlBuilder.append("sa.balance_frequency as balanceFrequency, ");
sqlBuilder.append("sa.account_closed_zero_balance_in_day_closing as accountClosedZeroBalanceInDayClosing, ");
sqlBuilder.append("sa.balance_swap_option as balanceSwapOption, sa.msme as msme, ");
sqlBuilder.append("sa.auto_debit_facility as autoDebitFacility, sa.loan_facility as loanFacility, ");
sqlBuilder.append("sa.premature_withdrawal_option as prematureWithdrawalOption, sa.tenure_flexibility as tenureFlexibility, ");
sqlBuilder.append("sa.lien_marked as lienMarked, sa.maturity_instructions as maturityInstructions, ");
sqlBuilder.append("sa.credit_maturity_proceeds as creditMaturityProceeds, ");
sqlBuilder.append("sa.penalty_grace_period_missed_installments as penaltyGracePeriodMissedInstallments, ");
sqlBuilder.append("sa.panel_request_applicable as panelRequestApplicable, ");
sqlBuilder.append("sa.no_penalty_nominee_heir_closure as noPenaltyNomineeHeirClosure, ");
sqlBuilder.append("sa.deceased_settlement as deceasedSettlement, ");
sqlBuilder.append("sa.allow_debit_txn_after_due_date as allowDebitTxnAfterDueDate ");
sqlBuilder.append(this.selectTablesSql());
sqlBuilder.append("left join m_deposit_product_recurring_detail dprd on sa.id = dprd.savings_product_id ");
sqlBuilder.append("left join m_code_value icv on icv.id = sa.interest_calculate_selector ");
this.schemaSql = sqlBuilder.toString();
}
@@ -1525,12 +1554,52 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
final BigDecimal totalOverdueAmount = null;
final Integer noOfOverdueInstallments = null;
return RecurringDepositAccountData.instance(depositAccountData, preClosurePenalApplicable, preClosurePenalInterest,
final RecurringDepositAccountData result = RecurringDepositAccountData.instance(depositAccountData,
preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
depositPeriodFrequencyType, mandatoryRecommendedDepositAmount, onAccountClosureType, expectedFirstDepositOnDate,
totalOverdueAmount, noOfOverdueInstallments, isMandatoryDeposit, allowWithdrawal, adjustAdvanceTowardsFuturePayments,
isCalendarInherited);
// CBS product fields
result.setCbsProductFields(
rs.getString("accountType"),
rs.getString("customerSegment"),
rs.getString("productCode"),
JdbcSupport.getLocalDate(rs, "effectiveDate"),
JdbcSupport.getLocalDate(rs, "effectiveTo"),
JdbcSupport.getLocalDate(rs, "endDate"),
rs.getBoolean("introducerRequired"),
rs.getBoolean("shareLinkingEnabled"),
rs.getBoolean("nominationFacility"),
rs.getBoolean("dormancyAlert"),
JdbcSupport.getInteger(rs, "interestCalculateSelector"),
rs.getString("interestCalculationTypeName"),
rs.getString("averagePeriod"),
rs.getBoolean("autoPost"),
JdbcSupport.getInteger(rs, "frequencyFixDay"),
JdbcSupport.getLocalDate(rs, "lastInterestDate"),
rs.getBoolean("enableLockinPeriod"),
rs.getString("balanceFrequency"),
rs.getBoolean("accountClosedZeroBalanceInDayClosing"),
rs.getBoolean("balanceSwapOption"),
rs.getBoolean("msme"),
rs.getBoolean("autoDebitFacility"),
rs.getBoolean("loanFacility"),
rs.getBoolean("prematureWithdrawalOption"),
rs.getBoolean("tenureFlexibility"),
rs.getBoolean("lienMarked"),
rs.getBoolean("maturityInstructions"),
rs.getBoolean("creditMaturityProceeds"),
rs.getBoolean("penaltyGracePeriodMissedInstallments"),
rs.getBoolean("panelRequestApplicable"),
rs.getBoolean("noPenaltyNomineeHeirClosure"),
rs.getBoolean("deceasedSettlement"),
rs.getBoolean("allowDebitTxnAfterDueDate")
);
return result;
}
}
@@ -304,7 +304,7 @@ public class DepositProductReadPlatformServiceImpl implements DepositProductRead
sqlBuilder.append("sp.effective_date as effectiveDate, sp.effective_to as effectiveTo, sp.end_date as endDate, ");
sqlBuilder.append("sp.introducer_required as introducerRequired, sp.share_linking_enabled as shareLinkingEnabled, ");
sqlBuilder.append("sp.nomination_facility as nominationFacility, sp.dormancy_alert as dormancyAlert, ");
sqlBuilder.append("sp.interest_calculate_selector as interestCalculateSelector, ");
sqlBuilder.append("sp.interest_calculate_selector as interestCalculateSelector, icv.code_value as interestCalculationTypeName, ");
sqlBuilder.append("sp.average_period as averagePeriod, ");
sqlBuilder.append("sp.auto_post as autoPost, sp.frequency_fix_day as frequencyFixDay, ");
sqlBuilder.append("sp.last_interest_date as lastInterestDate, sp.enable_lockin_period as enableLockinPeriod, ");
@@ -325,7 +325,8 @@ public class DepositProductReadPlatformServiceImpl implements DepositProductRead
sqlBuilder.append("left join m_deposit_product_term_and_preclosure dptp on sp.id=dptp.savings_product_id ");
sqlBuilder.append("left join m_deposit_product_recurring_detail dprd on sp.id=dprd.savings_product_id ");
sqlBuilder.append("join m_currency curr on curr.code = sp.currency_code ");
sqlBuilder.append(" left join m_tax_group tg on tg.id = sp.tax_group_id ");
sqlBuilder.append(" left join m_tax_group tg on tg.id = sp.tax_group_id ");
sqlBuilder.append("left join m_code_value icv on icv.id = sp.interest_calculate_selector ");
this.schemaSql = sqlBuilder.toString();
}
@@ -414,6 +415,7 @@ public class DepositProductReadPlatformServiceImpl implements DepositProductRead
result.setNominationFacility(nominationFacility);
result.setDormancyAlert(dormancyAlert);
result.setInterestCalculateSelector(interestCalculateSelector);
result.setInterestCalculationTypeName(rs.getString("interestCalculationTypeName"));
result.setAveragePeriod(averagePeriod);
result.setAutoPost(autoPost);
result.setFrequencyFixDay(frequencyFixDay);
@@ -25,6 +25,9 @@ import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
@@ -43,6 +46,7 @@ import org.apache.fineract.portfolio.client.data.ClientData;
import org.apache.fineract.portfolio.client.service.ClientReadPlatformService;
import org.apache.fineract.portfolio.group.data.GroupGeneralData;
import org.apache.fineract.portfolio.group.service.GroupReadPlatformService;
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;
@@ -62,6 +66,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.util.CollectionUtils;
@Slf4j
public class SavingsAccountTemplateReadPlatformServiceImpl implements SavingsAccountTemplateReadPlatformService {
private final PlatformSecurityContext context;
@@ -72,6 +77,7 @@ public class SavingsAccountTemplateReadPlatformServiceImpl implements SavingsAcc
private final StaffReadPlatformService staffReadPlatformService;
private final SavingsDropdownReadPlatformService dropdownReadPlatformService;
private final ChargeReadPlatformService chargeReadPlatformService;
private final CodeValueReadPlatformService codeValueReadPlatformService;
private final EntityDatatableChecksReadService entityDatatableChecksReadService;
@@ -80,7 +86,8 @@ public class SavingsAccountTemplateReadPlatformServiceImpl implements SavingsAcc
final SavingsProductReadPlatformService savingProductReadPlatformService,
final StaffReadPlatformService staffReadPlatformService, final SavingsDropdownReadPlatformService dropdownReadPlatformService,
final ChargeReadPlatformService chargeReadPlatformService,
final EntityDatatableChecksReadService entityDatatableChecksReadService, final ColumnValidator columnValidator) {
final EntityDatatableChecksReadService entityDatatableChecksReadService, final ColumnValidator columnValidator,
final CodeValueReadPlatformService codeValueReadPlatformService) {
this.context = context;
this.jdbcTemplate = jdbcTemplate;
this.clientReadPlatformService = clientReadPlatformService;
@@ -90,6 +97,7 @@ public class SavingsAccountTemplateReadPlatformServiceImpl implements SavingsAcc
this.dropdownReadPlatformService = dropdownReadPlatformService;
this.chargeReadPlatformService = chargeReadPlatformService;
this.entityDatatableChecksReadService = entityDatatableChecksReadService;
this.codeValueReadPlatformService = codeValueReadPlatformService;
}
@Override
@@ -176,6 +184,58 @@ public class SavingsAccountTemplateReadPlatformServiceImpl implements SavingsAcc
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions,
charges, chargeOptions);
// Enrich template with full CBS product data (classification, digital facilities, etc.)
try {
final SavingsProductData fullProduct = this.savingsProductReadPlatformService.retrieveOne(productId);
template.setAccountType(fullProduct.getAccountType());
template.setCustomerSegment(fullProduct.getCustomerSegment());
template.setProductCode(fullProduct.getProductCode());
template.setEffectiveDate(fullProduct.getEffectiveDate());
template.setEffectiveTo(fullProduct.getEffectiveTo());
template.setEndDate(fullProduct.getEndDate());
template.setIntroducerRequired(fullProduct.getIntroducerRequired());
template.setShareLinkingEnabled(fullProduct.getShareLinkingEnabled());
template.setNominationFacility(fullProduct.getNominationFacility());
template.setDormancyAlert(fullProduct.getDormancyAlert());
template.setInterestCalculationTypeName(fullProduct.getInterestCalculationTypeName());
template.setLastInterestDate(fullProduct.getLastInterestDate());
template.setEnableLockinPeriod(fullProduct.getEnableLockinPeriod());
template.setBalanceFrequency(fullProduct.getBalanceFrequency());
template.setAccountClosedZeroBalanceInDayClosing(fullProduct.getAccountClosedZeroBalanceInDayClosing());
template.setBalanceSwapOption(fullProduct.getBalanceSwapOption());
template.setMsme(fullProduct.getMsme());
template.setAutoDebitFacility(fullProduct.getAutoDebitFacility());
template.setAvgBalanceCalcPeriod(fullProduct.getAvgBalanceCalcPeriod());
template.setValidForPeriod(fullProduct.getValidForPeriod());
template.setOdAccountClosedZeroBalanceInDayClosing(fullProduct.getOdAccountClosedZeroBalanceInDayClosing());
template.setAccountFacilityConfig(fullProduct.getAccountFacilityConfig());
template.setAccountFacilityLimits(fullProduct.getAccountFacilityLimits());
template.setDepositLimitKyc(fullProduct.getDepositLimitKyc());
// CBS Term fields
template.setInterestCalculateSelector(fullProduct.getInterestCalculateSelector());
template.setAveragePeriod(fullProduct.getAveragePeriod());
template.setAutoPost(fullProduct.getAutoPost());
template.setFrequencyFixDay(fullProduct.getFrequencyFixDay());
// CBS dropdown options (fetched from code values, same as product template page)
final Collection<EnumOptionData> interestCalculationTypeOption = this.codeValueReadPlatformService
.retrieveCodeValuesByCode(SavingsApiConstants.INTEREST_CALCULATION_TYPE_OPTION).stream()
.map(cv -> new EnumOptionData(cv.getId(),
"interestCalculationTypeOption." + cv.getName().toLowerCase(Locale.ROOT).replace(' ', '_'),
cv.getName()))
.toList();
template.setInterestCalculationTypeOption(interestCalculationTypeOption);
final Collection<EnumOptionData> periodFrequencyOptions = this.codeValueReadPlatformService
.retrieveCodeValuesByCode(SavingsApiConstants.PERIOD_FREQUENCY).stream()
.map(cv -> new EnumOptionData(cv.getId(),
"periodFrequencyType." + cv.getName().toLowerCase(Locale.ROOT).replace(' ', '_'),
cv.getName()))
.toList();
template.setPeriodFrequencyOptions(periodFrequencyOptions);
} catch (final Exception e) {
log.warn("Failed to enrich savings account template with CBS product data for productId={}: {}", productId, e.getMessage());
}
} else {
String clientName = null;
@@ -213,7 +213,7 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
sqlBuilder.append("sp.effective_date as effectiveDate, sp.effective_to as effectiveTo, sp.end_date as endDate, ");
sqlBuilder.append("sp.introducer_required as introducerRequired, sp.share_linking_enabled as shareLinkingEnabled, ");
sqlBuilder.append("sp.nomination_facility as nominationFacility, sp.dormancy_alert as dormancyAlert, ");
sqlBuilder.append("sp.interest_calculate_selector as interestCalculateSelector, sp.average_period as averagePeriod, ");
sqlBuilder.append("sp.interest_calculate_selector as interestCalculateSelector, icv.code_value as interestCalculationTypeName, sp.average_period as averagePeriod, ");
sqlBuilder.append("sp.auto_post as autoPost, sp.frequency_fix_day as frequencyFixDay, sp.last_interest_date as lastInterestDate, ");
sqlBuilder.append("sp.enable_lockin_period as enableLockinPeriod, ");
sqlBuilder.append("sp.balance_frequency as balanceFrequency, ");
@@ -221,7 +221,8 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
sqlBuilder.append("from m_savings_product sp ");
sqlBuilder.append("join m_currency curr on curr.code = sp.currency_code ");
sqlBuilder.append("left join m_tax_group tg on tg.id = sp.tax_group_id ");
sqlBuilder.append("left join m_tax_group tg on tg.id = sp.tax_group_id ");
sqlBuilder.append("left join m_code_value icv on icv.id = sp.interest_calculate_selector ");
this.schemaSql = sqlBuilder.toString();
}
@@ -328,6 +329,7 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
productData.setNominationFacility(rs.getBoolean("nominationFacility"));
productData.setDormancyAlert(rs.getBoolean("dormancyAlert"));
productData.setInterestCalculateSelector(JdbcSupport.getInteger(rs, "interestCalculateSelector"));
productData.setInterestCalculationTypeName(rs.getString("interestCalculationTypeName"));
productData.setAveragePeriod(rs.getString("averagePeriod"));
productData.setAutoPost(rs.getBoolean("autoPost"));
productData.setFrequencyFixDay(JdbcSupport.getInteger(rs, "frequencyFixDay"));
@@ -370,10 +370,10 @@ public class SavingsConfiguration {
GroupReadPlatformService groupReadPlatformService, SavingsProductReadPlatformService savingProductReadPlatformService,
StaffReadPlatformService staffReadPlatformService, SavingsDropdownReadPlatformService dropdownReadPlatformService,
ChargeReadPlatformService chargeReadPlatformService, EntityDatatableChecksReadService entityDatatableChecksReadService,
ColumnValidator columnValidator) {
ColumnValidator columnValidator, CodeValueReadPlatformService codeValueReadPlatformService) {
return new SavingsAccountTemplateReadPlatformServiceImpl(context, jdbcTemplate, clientReadPlatformService, groupReadPlatformService,
savingProductReadPlatformService, staffReadPlatformService, dropdownReadPlatformService, chargeReadPlatformService,
entityDatatableChecksReadService, columnValidator);
entityDatatableChecksReadService, columnValidator, codeValueReadPlatformService);
}
@Bean